天天看點

初步探索java中的UUID概念代碼Time-based UUID

概念

java中的UUID可用來生成随機數,表示128位,即16位元組的值。

那麼UUID會重複嗎?

重複是肯定會重複的,32位的UUID,經過16^32+1次生成後,必然會産生至少一次重複,當然,不追求這個必然,偶然産生一次重複需要的平均次數比這個少得多。 不過……後面轉折來了,16^32=……沒算錯的話有39位數啊,你每秒并發10000次(你在Google工作也不一定能遇到這種場景),3600秒×24小時×365天不斷的并發,需要連續并發1000000……000000年(27個0,我不知道怎麼讀了),基本上宇宙毀滅之前,你也很難遇到重複的情況,SO,如果你認為純粹靠運氣連續100年每天中一次500W的事情是“絕對”不可能出現的話(這個機率比UUID重複來的還要容易些),UUID就是“絕對”不可能重複的。(該問題回答轉載自該處)

代碼

java

System.out.println("--------随機生成UUID  版本号4-------------");
        UUID uuid_random = UUID.randomUUID(); 
        System.out.println("uuid的值:     " + uuid_random + "\n");
        System.out.println("取前16:   " + uuid_random.getMostSignificantBits());
        System.out.println("取後16:   " + uuid_random.getLeastSignificantBits() + '\n');

        System.out.println(">>UUID生成的種類:" + uuid_random.version());
        System.out.println("版本号具有以下含意:");
        System.out.println("     1 基于時間的 UUID  2 DCE 安全 UUID  3 基于名稱的 UUID  4 随機生成的 UUID \n");
        System.out.println(">>字元串去掉'-' ");
        String uuid_Name = uuid_random.toString(); //如:d1ee9700-2ff7-4234-970f-6a1e0ddc44fa(32個16進位數字)
        String[] uuid_Names = uuid_Name.split("-");
        String uuid_Name2 = "";
        for(String u : uuid_Names){
            uuid_Name2 += u;
        }
        System.out.println("uuid的值:     " + uuid_Name2 + "\n"); //字元串去掉‘-’

        System.out.println("---------------------------------------");
        System.out.println("測試UUID類的timestamp方法");
        UUID uuid2 = UUID.fromString("58e0a7d7-eebc-11d8-9669-0800200c9a66");
        System.out.println("Time stamp value : " + uuid2.timestamp());
           

在以上測試代碼中,UUID.fromString中的資料格式要按照8-4-4-4-12位數,并且要符合Time-based UUID的格式,否則會報錯:

初步探索java中的UUID概念代碼Time-based UUID

Time-based UUID

基于時間的UUID使用,除了版本和變體,可由3個部分組成:

  1. 時間戳 timestamp
  2. 時鐘辨別 clock ID,最初是基于随機數
  3. 結點ID node ID, 最好是IEEE802位址

timestap

timestap是60位值,自1582年10月15日00:00:000000000後100納秒的間隔。

如果沒有UTC時間可以獲得,可以使用目前時間。必須注意的是,有些情況下時間設定未來時對應的clock ID是會增加的。

一般情況下,程式員不會獲得自1582年10月15日以來100納秒的時間間隔,卻可以擷取1970年1月1日以來的毫秒精度。在這種情況下,從毫秒到納秒精度系統傳回的時間乘以10000,正确的開始日期添加一個偏移量122192928000000000。

clock ID

時鐘ID是一個14位值,如果一個新的時間戳比前一個時間戳更早使用(例如在一個時鐘脈沖相位差錯誤或重新開機後,時間是異步的),時鐘ID應該增加

node ID

結點ID會是一個IEEE 802 MAC位址又名“以太網位址”。IEEE 802位址應該是唯一的,盡管已知一些雜牌廠商會重複使用。UUID生成的位址可能來自機器的網卡,或其他可以控制或確定沒有其他裝置去使用的機器(或網卡)。(比如買了一張網卡,生成UUID并記錄下,在一個程式中使用它後銷毀這張網卡,或從IEEE 802位址購買了一系列的IEEE)。

在IEEE 802位址通常可以使用ipconfig/all或使用ifconfig eth0的指令,通常被稱為“硬體”或“實體”位址檢索,看起來是這樣的: 08:00:20:0C:9A:66(有時也用-或空間作分隔符)

生成Time-based UUID

timestamp

當時間戳有60bit十六進制值,如1d8 eebc 58e0a7d7,

對應的UUID為:58e0a7d7-eebc-11d8-9669-0800200c9a66

以時間為基礎的UUID,第三部分第1位是1

clockID

時鐘辨別為1669,放置在UUID的以下位置:58e0a7d7-eebc-1**1d8-9**669-0800200c9a66

nodeID

node ID是 08:00:20:0c:9a:66,如果node ID已經被生成過一次,那麼第一位不是08,而是09