㈠ mcu没有唯一的id,怎么生产一个唯一的id
虽然MCU芯片本身没有唯一的ID,但您可以使用多种技术源磨来生成一个唯一的ID,比如:
1. 使用外部EEPROM或FLASH存储器的固定地址作为每个设备的唯一ID。
2. MCU芯片集成了一些硬件模块,如MAC地址和UUID。这些标识符可以用于创建唯一的ID。
3. 实现自己缺笑的唯一ID生成算法,例如可以将设备的制造商ID、日期、序列号等信息组合在一起进行哈希计算,生成唯一的ID。
需要注意的是,生成唯一ID的方法取决于具体的应用场景和要求。在实际应用中,您可能需要考虑到ID的伏裂含唯一性、可靠性、易于管理等因素,以便更好地保障系统的安全性和稳定性。
㈡ android获取设备唯一ID(优化方案)
最近,因公司产品及客户需要,领导让我研究免存储设备ID,以及给出一个设备ID最佳的方案(可与存储相结合)。在研究过浏览器的fingerprient2js后,颇有心得,并且看网上似乎木有完美的解决方案,于是写了这篇文章,仅供需要的开发者参考。(该算法暂未进行验证,这里先给出一个jar包,后期我会在SDK中加入调查接口,分两个jar包(测试版和正式版),希望开发者能支持测试版,稳定后使用正式版。)
在产品中,首先肯定要尽量避免权限,其次考虑卸载APP后ID不一致的问题,再就是尽量结合存储,降低卸载或重装app时,设备ID改变的概率。最后,设计出合理方案,对造成不利的因素进行列举。
A.android_id:
什么是android_id呢?当设备在第一次启动时,系统会随机产生一个64位的数字,然后以16进制的形式保存在设备上,且API提供了获取这一参数的方法:
这就是android_id,当设备重新初始化或者刷机的时候,会被重置。
除此以外,android_id还有其他的bug,比如:
1.不同的设备可能会产生相同的android_id。
2.有的厂商设备无法获取android_id,会返回null。
3.对于CDMA的设备,ANDROID_ID和TelephonyManager.getDeviceId() 的值相同。
4.不同的android系统版本稳定性不同。
B.硬件序列号(SERIAL)
API给的解释是:
A hardware serial number, if available.(一个硬件的序列码,如果有效的话)
so,虽然我没有用几百台手机测试,也能知道这个值有时候是无效的,说的这么隐晦。
C.指纹
fingerprint:设备的唯一标识。由设备的多个信息拼接合成。
也是在javaScript才接触到这个单词”fingerprint“,这个词也很生动,意思是能大概的标识一个设备,像指纹一样,但不排除重复的可能性。
理论上讲用这个属性是可以标识一个设备的,但是其实并不是,两台一摸一样的新手机,这个值相同的可能性是很多的。为了更加进一步的精确,后面还会介绍几个属性,并把几个属性结合在一起,生成一个接近100%的UUID。
D.android系统提供了获取android系统版本号,生产厂商,固件版本推出时间的API.
E.android系统提供了当前android设备是12或24小时制显示时间的API,
F.android系统提供了当前android设备的修订版本列表,显示屏,主板等等参数。
G.可以允许用户根据需求用自定义字符串去为FP做贡献,比如IP地址等
方案:
在不需要用户权限的前提下,网上最完美的方案是将android_id和硬件序列号,如果其中任意一种失效就使用另外一种。受FingerPrint2js的启发,我看了Android获取系统硬件相关的API,将所有不经常变化且能代表一定用户群体的属性都取出来进行MD5运算,包含但不限于依据中所述的信息。准确性还需进一步验证,但理论上要比FingerPrint2js准确性高,也在网上给出的比较好的方案基础上进一步缩小了FP可能重复的概率。
1.第一次进入APP时,获取系统相关配置信息生成FP,存入SP。
2.每次访问,先从SP取,没有再通过相关配置信息生成FP,存入SP。
3.封装成jar,只给用户暴露出获取ID的接口、传递自定义信息构建FP的接口以及第一次安装时间戳的接口(或设置标签调用的接口)
单纯对于FP而言,有两个主要问题需要解决,一是FP重复的问题,相同配置的新设备重复可能性极大,增多给FP贡献的因素的数量,可以有效降低重复率。二是FP改变的问题,贡献FP的生成因素的其中一个如果改变,FP就会改变。所以如果FP的贡献因素数量过多,导致FP改变的概率也就变大,所以说客户要在两者之间做一个很好的平衡。
对比:
为android FP做贡献的各配置参数:(示例以6.0的华为荣耀8为例)
1.Android_ID:Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID) //低版本稳定,高版本不稳定 示例:295a4fbf716094ee
2.Build.SERIAL 设备序列号(有的设备无法获取) 示例:WTK7N16923005607
3.Build.FINGERPRINT 设备指纹(同样的新设备该值应该是一样的) 示例:honor/FRD-AL00/HWFRD:6.0/HUAWEIFRD-AL00/C00B171:user/release-keys
4.Build.TIME 固件推出日期 示例:1477442228000
5.Build.VERSION.INCREMENTAL 源码控制版本号 示例: C00B171
6.Build.getRadioVersion() 获取无线电固件版本 示例:21.210.03.00.031,21.210.03.00.031
7.Build.HARDWARE 硬件名称 示例:hi3650
8.Build.VERSION.SECURITY_PATCH 用户可见安全补丁level(这里我得到的是日期,可能是补丁修复的时间)示例:2016-10-01
9.当前设备是12/24时制:Settings.System.getString(context.getContentResolver(), Settings.System.TIME_12_24) 示例:null(有的手机可以获取)
10.Build.VERSION.SDK_INT SDK版本号 (一般讲是与系统版本号一一对应的) 示例:23
11.Build.SUPPORTED_32_BIT_ABIS 支持32位ABIs的列表(数值)示例:[armeabi-v7a,armeabi]
12.Build.SUPPORTED_64_BIT_ABIS 支持64位ABIs的列表(数值)示例:[arm64-v8a]
13.Build.BOOTLOADER 系统启动程序版本号 示例:unknown
14.Build.VERSION.RELEASE 用户可见版本 示例: 6.0
16.Build.BOARD 主板 示例:FRD-AL00
17.Build.BRAND 系统定制商 示例:honor
21.Build.HOST 示例:huawei-RH2288H-V2-12L
23.Build.MANUFACTURER 产品/硬件的制造商 示例:HUAWEI
25.Build.PRODUCT 产品的名称 示例:FRD-AL00
26.Build.TAGS 描述Build的标签(Comma-separated tags describing the build, like "unsigned,debug".) 示例:release-keys
28.Build.USER 描述Build的USER 示例:jslave
31.Build.VERSION.BASE_OS 基带版本 The base OS build the proct is based on. 示例:空值
32.自定义字符串或自定义数组
㈢ 如何保证数据库集群中id的唯一性,假设每秒钟并发20万次
用雪花算法的工具类,1秒内可以生成26万不重复的值,数据库的主键不要自增,手动设置
packageentity;
importjava.lang.management.ManagementFactory;
importjava.net.InetAddress;
importjava.net.NetworkInterface;
/**
*<p>名称:IdWorker.java</p>
*<p>描述:分布式自增长ID</p>
*<pre>
*Twitter的SnowflakeJAVA实现方案
*</pre>
*核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:
*1||0------00000---00000---000000000000
*在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,
*然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),
*然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
*这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),
*并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。
*<p>
*64位ID(42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
*
*@authorPolim
*/
publicclassIdWorker{
//时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
privatefinalstaticlongtwepoch=1288834974657L;
//机器标识位数
=5L;
//数据中心标识位数
=5L;
//机器ID最大值
=-1L^(-1L<<workerIdBits);
//数据中心ID最大值
=-1L^(-1L<<datacenterIdBits);
//毫秒内自增位
=12L;
//机器ID偏左移12位
=sequenceBits;
//数据中心ID左移17位
=sequenceBits+workerIdBits;
//时间毫秒左移22位
=sequenceBits+workerIdBits+datacenterIdBits;
=-1L^(-1L<<sequenceBits);
/*上次生产id时间戳*/
=-1L;
//0,并发控制
privatelongsequence=0L;
privatefinallongworkerId;
//数据标识id部分
privatefinallongdatacenterId;
publicIdWorker(){
this.datacenterId=getDatacenterId(maxDatacenterId);
this.workerId=getMaxWorkerId(datacenterId,maxWorkerId);
}
/**
*@paramworkerId
*工作机器ID
*@paramdatacenterId
*序列号
*/
publicIdWorker(longworkerId,longdatacenterId){
if(workerId>maxWorkerId||workerId<0){
(String.format("workerIdcan'tbegreaterthan%dorlessthan0",maxWorkerId));
}
if(datacenterId>maxDatacenterId||datacenterId<0){
(String.format("datacenterIdcan'tbegreaterthan%dorlessthan0",maxDatacenterId));
}
this.workerId=workerId;
this.datacenterId=datacenterId;
}
/**
*获取下一个ID
*
*@return
*/
publicsynchronizedlongnextId(){
longtimestamp=timeGen();
if(timestamp<lastTimestamp){
thrownewRuntimeException(String.format("Clockmovedbackwards.Refusingtogenerateidfor%dmilliseconds",lastTimestamp-timestamp));
}
if(lastTimestamp==timestamp){
//当前毫秒内,则+1
sequence=(sequence+1)&sequenceMask;
if(sequence==0){
//当前毫秒内计数满了,则等待下一秒
timestamp=tilNextMillis(lastTimestamp);
}
}else{
sequence=0L;
}
lastTimestamp=timestamp;
//ID偏移组合生成最终的ID,并返回ID
longnextId=((timestamp-twepoch)<<timestampLeftShift)
|(datacenterId<<datacenterIdShift)
|(workerId<<workerIdShift)|sequence;
returnnextId;
}
privatelongtilNextMillis(finallonglastTimestamp){
longtimestamp=this.timeGen();
while(timestamp<=lastTimestamp){
timestamp=this.timeGen();
}
returntimestamp;
}
privatelongtimeGen(){
returnSystem.currentTimeMillis();
}
/**
*<p>
*获取maxWorkerId
*</p>
*/
(longdatacenterId,longmaxWorkerId){
StringBuffermpid=newStringBuffer();
mpid.append(datacenterId);
Stringname=ManagementFactory.getRuntimeMXBean().getName();
if(!name.isEmpty()){
/*
*GETjvmPid
*/
mpid.append(name.split("@")[0]);
}
/*
*MAC+PID的hashcode获取16个低位
*/
return(mpid.toString().hashCode()&0xffff)%(maxWorkerId+1);
}
/**
*<p>
*数据标识id部分
*</p>
*/
(longmaxDatacenterId){
longid=0L;
try{
InetAddressip=InetAddress.getLocalHost();
NetworkInterfacenetwork=NetworkInterface.getByInetAddress(ip);
if(network==null){
id=1L;
}else{
byte[]mac=network.getHardwareAddress();
id=((0x000000FF&(long)mac[mac.length-1])
|(0x0000FF00&(((long)mac[mac.length-2])<<8)))>>6;
id=id%(maxDatacenterId+1);
}
}catch(Exceptione){
System.out.println("getDatacenterId:"+e.getMessage());
}
returnid;
}
publicstaticvoidmain(String[]args){
//推特26万个不重复的ID
IdWorkeridWorker=newIdWorker(0,0);
for(inti=0;i<2600;i++){
System.out.println(idWorker.nextId());
}
}
}
㈣ Guid的生成算法是什么样的
GUID globally unique identifier(全球唯一标识符) 分配给COM对象的标识符(ID)。它通过一种复杂的算法生成,该算法保证所有的COM对稿圆象都有着唯一的ID,而不会出现名字冲突。 GUID(全球唯一标哗顷识)是微软使用的一个术键芦塌语,由一个特定的算法,
㈤ 分布式全局ID自增算法
stub代表一个业务
这种情况有可能因为从库没来得及同步从而生成重复的ID
双主设置中,
其中一台机器值生成奇数ID
其中一台机器值生成偶数ID
业务随机从其中一个机器中取出一个ID,如果其中一台挂了,直接从另外一台生成。
1.简单 2.ID递增
1.并发量不够高
2.水平扩展困难
3.安全困态岁系数低
incrby key n //n为步长,key代表一个业务
单点吞吐不够,可以使用集群
同一个key在不同的节点上的初始值不同,步长相同,可以保证节点之汪睁间的value不相同
1.性能更好
2.ID递增
1.水平扩展困难
2.集群宕机会导致产生重复id
UUID是一组32位的16进制数字,理论上总数为16^32 = 2 ^ 128个
UUID是利用同一时空中的所有机器都是唯一的这一规则来确保唯一性的。
UUID通过系统时间,时钟序列以及全局唯一的机器识别,例如网卡MAC,机器SN等
相对安全,可以保证ID唯闭渗一
1.存储麻烦,太长了
2.无法自增
通过上面可以知道,最多可以是2 ^ 10 = 1024个全局唯一节点,最后12bit表示每毫秒生成的一个id序号。
㈥ 如何获得stm32 cpu的唯一ID
STM32每一个芯片内部都有一个唯一的96位的ID号,可以通关过以下方式进行读取:
由于唯一ID是一个96位的数据,所以你要创建3个32位变量用于存储ID号
static u32 CpuID[3];
接着执行读取函:
void GetLockCode(void)
{
//获取CPU唯一ID
CpuID[0]=*(vu32*)(0x1ffff7e8);
CpuID[1]=*(vu32*)(0x1ffff7ec);
CpuID[2]=*(vu32*)(0x1ffff7f0);
}
数就可以了。
㈦ 如何读取STM32的唯一ID
1,如果板子上有外部存储器,可以先编写一个程序,利用算法把id计算得到一些值存入外部存判拿储器,然后再烧写真正的程序,真正的程序去校验外部存储器的数据是否合法即可
2,利用板子上掘旦搭按键组合,或是上电按住某些键,程序在这个时候利用算法把id计算得到一些值存入程序区(stm8为EE区),程序运行时去验证程序区数据是否正确
3,轩微编程器有软件加密的功能,编程器会读芯片id,根据算法直接改写缓冲区,达到软件加密的作用
4,读出的id通过一定算法,例如异或加上一个数,得到的数据存入flash(只运行一次,运行后标志位也存入flash),下次读到这个标志位,就不运行这个程序。
四、迟宴做软件加密时注意
1,不要在程序中直接出现id地址,例如STM32:1FFFF7E8 1FFFF7EC 1FFFF7F0 STM8: 0x4865~0x4870
2, 利用校验和或是crc对程序区进行校验,防止改程序
㈧ 分布式ID-Leaf
用身份证号码推导分布式id(雪花岁迅租算法)
因我们用10进制,18位身份证号足够。而计算机用2进制,id要足够长,用long,64位
分布式id算法具备的条昌悄件:全局唯一、局部唯一、按情况保持递增
Leaf=snowflake+segment
极致提高一个服务器性能,可以从以下几方面入手:
Leaf的数据表
参考"极致乎兆提高一个服务器性能",套用Leaf
雪花算法ID由long64位组成,其中含有时间戳。图中举例它的组成,实际并不是这样组成的,只要保证 全局唯一、局部唯一、按情况保持递增 即可
雪花算法有明显的弊端
上面两点,都可以通过zk进行解决。
针对问题2的解决方法:
利用zk创建持久节点的顺序性去分配nodeId和areaId
针对问题1的解决方法:
㈨ pythonredis生成唯一id原理
pythonredis生成唯一id原唤橘虚理
答:1. 安装toollib 执行和燃命令:pip install toollib
2. 调用方法 from toollib.guid import RedisUid from toollib.redis_cli import RedisCli redis_cli = RedisCli(host='127.0.0.1')
Python生成唯一ID几种方式 - 知乎
1. 原理 Snowflake是Twitter提出的一个算法,其目伍清的是生成一个64位的整数;
㈩ 如何为每部Android手机生成一个唯一的ID
这种方法是,以一些特定的信息为基础,生成设备的唯一标识。
首先,算法角度,常用的有UUID、摘要两种。这两种算法都是以特定的数据为基础,生成一个唯一的、固定长度的字符串。这里选择UUID。
其次,计算的基础数据,建议选择divice_id和android_id。原因是,1)这两个标识虽然不能抵抗wipe操作,但受用户的行为影响比较小;2)如果正常获取,都是唯一的;③如果不能正常获取,结果也是固定的,不会频繁变化。
再次,优先级的考虑。从这两个标识的缺点考虑。
1)device_id。
①不能标识非手机设备,例如Pad。
②权限问题,因为用户的反感。
③获取异常,厂商定制系统中存在的bug,致使返回结果为空,或者为一串“0”或“*”。
④对于双卡双待手机,会返回两个device_id。
2)android_id。
①Android2.3以前,系统Bug,导致不同的设备产生相同的结果:9774d56d682e549c。
②有些可能返回null。
③设备差异:对于CDMA设备,与device_id返回相同的值。
综合考虑,device_id不能标识某些pad,以及用户的权限问题,是我们不能接受的,所以优先使用android_id。对于android_id返回为null的情况,再考虑使用device_id。
最后,当android_id和device_id都返回异常的情况,我们可以随机生成一个UUID。