㈠ 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。