最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java代碼獲取UUID的實(shí)現(xiàn)示例

 更新時(shí)間:2023年06月02日 11:01:59   作者:西晉的no1  
本文主要介紹了java代碼獲取UUID的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

什么是UUID

UUID 是指(Universally Unique Identifier)通用唯一識(shí)別碼,128位。RFC 4122描述了具體的規(guī)范實(shí)現(xiàn)。

現(xiàn)實(shí)問(wèn)題

我們開(kāi)發(fā)的時(shí)候,數(shù)據(jù)庫(kù)表總會(huì)有一個(gè)主鍵,以前我們可能會(huì)使用自增的數(shù)字作為主鍵。這樣做去確實(shí)查詢的時(shí)候比較快, 但是在做系統(tǒng)集成或者數(shù)據(jù)遷移的的時(shí)候就麻煩了。這是id就有可能重復(fù)了。那么有什么比較好的方法解決這一問(wèn)題呢? 于是jdk1.5出了UUID這個(gè)類(lèi)來(lái)生成唯一的字符串標(biāo)識(shí)。

UUID作用

UUID 的目的是讓分布式系統(tǒng)中的所有元素都能有唯一的識(shí)別信息。如此一來(lái),每個(gè)人都可以創(chuàng)建不與其它人沖突的 UUID,就不需考慮數(shù)據(jù)庫(kù)創(chuàng)建時(shí)的名稱(chēng)重復(fù)問(wèn)題。其作用視場(chǎng)景而定。

目前最廣泛應(yīng)用的 UUID,即是微軟的 Microsoft's Globally Unique Identifiers (GUIDs),而其他重要的應(yīng)用, 則有 Linux ext2/ext3 檔案系統(tǒng)、LUKS 加密分割區(qū)、GNOME、KDE、Mac OS X 等等。

UUID定義

UUID使用16進(jìn)制表示,共有36個(gè)字符(32個(gè)字母/數(shù)字+4個(gè)連接符"-")組成,格式為8-4-4-4-12 ;【一個(gè)字母/數(shù)字只代表4個(gè)bit,所以是(8+4+4+4+12)*4=128位;】

由一組32個(gè)16進(jìn)制數(shù)碼(0-9a-z)所構(gòu)成,故 UUID 理論上的總數(shù)為,約等于

也就是說(shuō)若每納秒產(chǎn)生1百萬(wàn)個(gè) UUID,要花100億年才會(huì)將所有 UUID 用完。

格式:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

示例:

96b31816-ae1c-11ed-904f-4531ee40a9e3

格式中M和N都有具體的含義

數(shù)字 M的四位表示 UUID 版本,當(dāng)前規(guī)范有5個(gè)版本,M可選值為1, 2, 3, 4, 5 ;

數(shù)字 N的一至四個(gè)最高有效位表示 UUID 變體( variant ),有固定的兩位10xx因此只可能取值8, 9, a, b。

這5個(gè)版本使用不同算法,利用不同的信息來(lái)產(chǎn)生UUID,各版本有各自優(yōu)勢(shì),適用于不同情景。具體使用的信息

  • 版本 1:UUID 是根據(jù)時(shí)間和 MAC 地址生成的;
  • 版本 2:UUID 是根據(jù)標(biāo)識(shí)符(通常是組或用戶 ID)、時(shí)間和節(jié)點(diǎn) ID生成的;
  • 版本 3:UUID 是通過(guò)散列(MD5 作為散列算法)名字空間(namespace)標(biāo)識(shí)符和名稱(chēng)生成的;
  • 版本 4:UUID 使用隨機(jī)性或偽隨機(jī)性生成;
  • 版本 5:類(lèi)似于版本 3(SHA1 作為散列算法)。

故UUID每個(gè)版本不是根據(jù)精度區(qū)分的,Version5并不會(huì)比Version1精度高,在精度上,大家都能保證唯一性,重復(fù)的概率近乎于0。

為了能兼容過(guò)去的 UUID,以及應(yīng)對(duì)未來(lái)的變化,因此有了變體(Variants)這一概念。

目前已知的變體有下面 4 種:

  • 變體 0:格式為 0xxx,為了向后兼容預(yù)留。
  • 變體 1:格式為 10xx,當(dāng)前正在使用的。
  • 變體 2:格式為 11xx,為早期微軟的 GUID 預(yù)留。
  • 變體 3:格式為 111x,為將來(lái)的擴(kuò)展預(yù)留,目前暫未使用。

在上例中,M 是 1,N 是 a(二進(jìn)制為 1010,符合 10xx 的格式),這就意味著這個(gè) UUID 是“版本 1”、“變體 1”的 UUID。

目前大多數(shù)使用的 UUID 大都是變體 1,N 的取值是 8、9、a、b 中的一個(gè)。

version 1——date-time & MAC address

基于時(shí)間戳及MAC地址的UUID實(shí)現(xiàn)。它包括了48位的MAC地址和60位的時(shí)間戳,

v1為了保證唯一性,當(dāng)時(shí)間精度不夠時(shí),會(huì)使用13~14位的clock sequence來(lái)擴(kuò)展時(shí)間戳,比如:

當(dāng)UUID的生產(chǎn)成速率太快,超過(guò)了系統(tǒng)時(shí)間的精度。時(shí)間戳的低位部分會(huì)每增加一個(gè)UUID就+1的操作來(lái)模擬更高精度的時(shí)間戳,換句話說(shuō),就是當(dāng)系統(tǒng)時(shí)間精度無(wú)會(huì)區(qū)分2個(gè)UUID的時(shí)間先后時(shí),為了保證唯一性,會(huì)在其中一個(gè)UUID上+1。所以UUID重復(fù)的概率幾乎為0,時(shí)間戳加擴(kuò)展的clock sequence一共有74bits,(2的74次方,約為1.8后面加22個(gè)零),即在每個(gè)節(jié)點(diǎn)下,每秒可產(chǎn)生1630億不重復(fù)的UUID(因?yàn)橹痪_到了秒,不再是74位,所以換算了一下)。

相對(duì)于其它版本,v1還加入48位的MAC地址,這依賴(lài)于網(wǎng)卡供應(yīng)商能提供唯一的MAC地址,同時(shí)也可能通過(guò)它反查到對(duì)應(yīng)的MAC地址。Melissa病毒就是這樣做到的。

Version2(date-time Mac address)

這是最神秘的版本,RFC沒(méi)有提供具體的實(shí)現(xiàn)細(xì)節(jié),以至于大部分的UUID庫(kù)都沒(méi)有實(shí)現(xiàn)它,只在特定的場(chǎng)景(DCE security)才會(huì)用到。所以絕大數(shù)情況,我們也不會(huì)碰到它。

Version3,5(namespace name-based)

V3和V5都是通過(guò)hash namespace的標(biāo)識(shí)符和名稱(chēng)生成的。V3使用MD5作為hash函數(shù),V5則使用SHA-1。

因?yàn)槔锩鏇](méi)有不確定的部分,所以當(dāng)namespace與輸入?yún)?shù)確定時(shí),得到的UUID都是確定唯一的。

具體的流程就是

把namespace和輸入?yún)?shù)拼接在一起,如"http/http://wwwbaidu.com" ++ "/query=uuid";

使用MD5算法對(duì)拼接后的字串進(jìn)行hash,截?cái)酁?28位;

把UUID的Version和variant字段都替換成固定的;

如果需要to_string,需要轉(zhuǎn)為16進(jìn)制和加上連接符"-"。

把V3的hash算法由MD5換成SHA-1就成了V5。

Version4(random)

這個(gè)版本使用最為廣泛:

其中4位代表版本,2-3位代表variant。余下的122-121位都是全部隨機(jī)的。即有2的122次方(5.3后面36個(gè)0)個(gè)UUID。一個(gè)標(biāo)準(zhǔn)實(shí)現(xiàn)的UUID庫(kù)在生成了2.71萬(wàn)億個(gè)UUID會(huì)產(chǎn)生重復(fù)UUID的可能性也只有50%的概率:

這相當(dāng)于每秒產(chǎn)生10億的UUID,持續(xù)85年,而把這些UUID都存入文件,每個(gè)UUID占16bytes,總需要45 EB(exabytes),比目前最大的數(shù)據(jù)庫(kù)(PB)還要大很多倍。

UUID的重復(fù)概率

Java中 UUID 使用版本4進(jìn)行實(shí)現(xiàn),所以由java.util.UUID類(lèi)產(chǎn)生的 UUID,128個(gè)比特中,有122個(gè)比特是隨機(jī)產(chǎn)生,4個(gè)比特標(biāo)識(shí)版本被使用,還有2個(gè)標(biāo)識(shí)變體被使用。利用生日悖論,可計(jì)算出兩筆 UUID 擁有相同值的機(jī)率約為

其中x為 UUID 的取值范圍,n為 UUID 的個(gè)數(shù)。

以下是以 x =

計(jì)算出n筆 UUID 后產(chǎn)生碰撞的機(jī)率:

換句話說(shuō),每秒產(chǎn)生10億筆 UUID ,100年后只產(chǎn)生一次重復(fù)的機(jī)率是50%。如果地球上每個(gè)人都各有6億筆 UUID,發(fā)生一次重復(fù)的機(jī)率是50%。與被隕石擊中的機(jī)率比較的話,已知一個(gè)人每年被隕石擊中的機(jī)率估計(jì)為170億分之1,也就是說(shuō)機(jī)率大約是0.00000000006 (6 x ),等同于在一年內(nèi)生產(chǎn)2000億個(gè) UUID 并發(fā)生一次重復(fù)。

Java獲取uuid示例

使用 JDK 原生的API

import java.util.UUID;
public class Test {
    public static void main(String[] args) {
        // JDK 原生的 API 獲取UUID
        // uuid版本3獲取uuid
        UUID uuid3 = UUID.nameUUIDFromBytes("test".getBytes());
        int version3 = uuid3.version();
        System.out.println("UUID3:" + uuid3 + " 版本 " + version3);
        // uuid版本4獲取uuid
        UUID uuid4 = UUID.randomUUID();
        int version4 = uuid4.version();
        System.out.println("UUID4:" + uuid4 + " 版本 " + version4);
        // 生成一個(gè)基于指定 UUID 字符串的 UUID 對(duì)象
        UUID uuid = UUID.fromString("098f6bcd-4621-3373-8ade-4e832627b4f6");
        int version = uuid.version();
        System.out.println("UUID_fromString:" + uuid + " 版本 " + version);
    }
}

nameUUIDFromBytes() 會(huì)生成一個(gè)版本 3 的UUID,不過(guò)需要傳遞一個(gè)名稱(chēng)的字節(jié)數(shù)組作為參數(shù)。

randomUUID() 方法生成了一個(gè)版本 4 的 UUID,這也是生成 UUID最方便的方法。如果只使用原生 JDK 的話,基本上都用的這種方式。

fromString() 方法會(huì)生成一個(gè)基于指定 UUID 字符串的 UUID對(duì)象,如果指定的 UUID 字符串不符合 UUID 的格式,將拋出 IllegalArgumentException 異常。

使用com.fasterxml.uuid.Generators

除了使用 JDK 原生的 API 之外,還可以使用com.fasterxml.uuid.Generators,需要先在項(xiàng)目中加入該類(lèi)的 Maven 依賴(lài)。

<dependencies>
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>3.1.4</version>
</dependency>
</dependencies>

代碼:

import com.fasterxml.uuid.Generators;
import java.util.UUID;
public class Test {
    public static void main(String[] args) {
        // JDK 原生的 API 獲取UUID
        // uuid版本1獲取uuid
        UUID uuid1 = Generators.timeBasedGenerator().generate();
        System.out.println("UUID : " + uuid1);
        System.out.println("UUID 版本 : " + uuid1.version());
        // uuid版本4獲取uuid
        UUID uuid2 = Generators.randomBasedGenerator().generate();
        System.out.println("UUID : " + uuid2);
        System.out.println("UUID 版本 : " + uuid2.version());
    }
}

Generators.timeBasedGenerator().generate() 可用于生成版本1 的 UUID,Generators.randomBasedGenerator().generate() 可用于生成版本4 的 UUID。

總結(jié)

使用較多的是版本1和版本4,其中版本1使用當(dāng)前時(shí)間戳和MAC地址信息。版本4使用(偽)隨機(jī)數(shù)信息,128bit中,除去版本確定的4bit和variant確定的2bit,其它122bit全部由(偽)隨機(jī)數(shù)信息確定。

因?yàn)闀r(shí)間戳和隨機(jī)數(shù)的唯一性,版本1和版本4總是生成唯一的標(biāo)識(shí)符。若希望對(duì)給定的一個(gè)字符串總是能生成相同的 UUID,使用版本3或版本5。如果只是需要生成一個(gè)唯一ID,你可以使用V1或V4。

- V1基于時(shí)間戳和Mac地址,這些ID有一定的規(guī)律(你給出一個(gè),是有可能被猜出來(lái)下一個(gè)是多少的),而且會(huì)暴露你的Mac地址。

- V4是完全隨機(jī)(偽)的。

如果對(duì)于相同的參數(shù)需要輸出相同的UUID,你可以使用V3或V5。

- V3基于MD5 hash算法,如果需要考慮與其它系統(tǒng)的兼容性的話,就用它,因?yàn)樗鰜?lái)得早,大概率大家都是用它的。

- V5基于SHA-1 hash算法,這個(gè)是首選。

到此這篇關(guān)于java代碼獲取UUID的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)java獲取UUID內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于Java應(yīng)用日志與Jaeger的trace關(guān)聯(lián)的問(wèn)題

    關(guān)于Java應(yīng)用日志與Jaeger的trace關(guān)聯(lián)的問(wèn)題

    這篇文章主要介紹了Java應(yīng)用日志如何與Jaeger的trace關(guān)聯(lián),通過(guò)jaeger發(fā)現(xiàn)這十次請(qǐng)求中有一次耗時(shí)特別長(zhǎng),想定位一下具體原因,感興趣的朋友跟隨小編一起看看吧
    2022-01-01
  • Java實(shí)現(xiàn)復(fù)原IP地址的方法

    Java實(shí)現(xiàn)復(fù)原IP地址的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)復(fù)原IP地址的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • SpringBoot整合Mail發(fā)送郵件功能

    SpringBoot整合Mail發(fā)送郵件功能

    我們?cè)诰W(wǎng)站上注冊(cè)賬號(hào)的時(shí)候一般需要獲取驗(yàn)證碼,而這個(gè)驗(yàn)證碼一般發(fā)送在你的手機(jī)號(hào)上還有的是發(fā)送在你的郵箱中,注冊(cè),賬號(hào)密碼…都需要用到驗(yàn)證,今天就演示一下如何用SpringBoot整合Mail發(fā)送郵箱
    2021-11-11
  • Spring Boot 中 controller層注解常用方法詳解

    Spring Boot 中 controller層注解常用方法詳解

    在 Spring Boot 中,@RestController 是一個(gè)用于處理 RESTful 風(fēng)格請(qǐng)求的組合注解,它結(jié)合了 @Controller 和 @ResponseBody,使得返回的對(duì)象直接轉(zhuǎn)換成 JSON 或 XML 格式,無(wú)需視圖解析,本文重點(diǎn)介紹Spring Boot 中 controller層注解常用方法,感興趣的朋友一起看看吧
    2025-10-10
  • Java 實(shí)現(xiàn)微信和支付寶支付功能

    Java 實(shí)現(xiàn)微信和支付寶支付功能

    這篇文章主要介紹了Java 實(shí)現(xiàn)微信和支付寶支付功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Java中的權(quán)重算法(如Dubbo的負(fù)載均衡權(quán)重)詳解

    Java中的權(quán)重算法(如Dubbo的負(fù)載均衡權(quán)重)詳解

    這篇文章主要介紹了Java中的權(quán)重算法(如Dubbo的負(fù)載均衡權(quán)重)詳解,負(fù)載均衡,其含義就是指將負(fù)載進(jìn)行平衡、分?jǐn)偟蕉鄠€(gè)操作單元上進(jìn)行運(yùn)行,例如FTP服務(wù)器、Web服務(wù)器、企業(yè)核心應(yīng)用服務(wù)器和其它主要任務(wù)服務(wù)器等,從而協(xié)同完成工作任務(wù),需要的朋友可以參考下
    2023-08-08
  • 淺談Java安全之C3P0鏈利用與分析

    淺談Java安全之C3P0鏈利用與分析

    本文主要介紹了淺談Java安全之C3P0鏈利用與分析,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 一文帶你解讀所有HashMap的面試題

    一文帶你解讀所有HashMap的面試題

    HashMap在面試的時(shí)候,是非常容易被問(wèn)到的。因?yàn)樵贘DK8出來(lái)之后,非常容易被問(wèn)到關(guān)于HashMap的知識(shí)點(diǎn),而如果對(duì)于沒(méi)有研究過(guò)他的源代碼的同學(xué)來(lái)說(shuō),這個(gè)可能只是說(shuō)出一部分來(lái)。本文就把HashMap上面大部分會(huì)被在面試中問(wèn)到的內(nèi)容,做個(gè)總結(jié),希望有所幫助
    2022-09-09
  • Java基于socket服務(wù)實(shí)現(xiàn)UDP協(xié)議的方法

    Java基于socket服務(wù)實(shí)現(xiàn)UDP協(xié)議的方法

    這篇文章主要介紹了Java基于socket服務(wù)實(shí)現(xiàn)UDP協(xié)議的方法,通過(guò)兩個(gè)簡(jiǎn)單實(shí)例分析了java通過(guò)socket實(shí)現(xiàn)UDP發(fā)送與接收的技巧,需要的朋友可以參考下
    2015-05-05
  • Java并發(fā)中ThreadLocal的使用指南與常見(jiàn)陷阱

    Java并發(fā)中ThreadLocal的使用指南與常見(jiàn)陷阱

    在 Java 并發(fā)編程中,ThreadLocal 是解決線程安全、簡(jiǎn)化上下文傳遞的高頻利器,本文補(bǔ)充了多數(shù)據(jù)存儲(chǔ)規(guī)則與initialValue()兜底邏輯,結(jié)合底層原理、最佳實(shí)踐與避坑指南,全面拆解 ThreadLocal,需要的朋友可以參考下
    2026-03-03

最新評(píng)論

南充市| 永济市| 新平| 尉犁县| 泸溪县| 德清县| 祁连县| 五寨县| 东乌珠穆沁旗| 涡阳县| 佛教| 长子县| 峨边| 泾川县| 井研县| 灵宝市| 濮阳县| 集贤县| 张家口市| 巴林右旗| 奈曼旗| 玉田县| 陆良县| 安化县| 德令哈市| 双江| 仁寿县| 南昌市| 上虞市| 子洲县| 雅江县| 锦屏县| 中山市| 铅山县| 大石桥市| 西城区| 子长县| 泸溪县| 克什克腾旗| 房产| 井研县|