UUID简介以及java代码获取UUID示例

这篇具有很好参考价值的文章主要介绍了UUID简介以及java代码获取UUID示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是UUID

UUID 是指(Universally Unique Identifier)通用唯一识别码,128位。RFC 4122描述了具体的规范实现。

现实问题

我们开发的时候,数据库表总会有一个主键,以前我们可能会使用自增的数字作为主键。这样做去确实查询的时候比较快, 但是在做系统集成或者数据迁移的的时候就麻烦了。这是id就有可能重复了。那么有什么比较好的方法解决这一问题呢? 于是jdk1.5出了UUID这个类来生成唯一的字符串标识。

UUID作用

UUID 的目的是让分布式系统中的所有元素都能有唯一的识别信息。如此一来,每个人都可以创建不与其它人冲突的 UUID,就不需考虑数据库创建时的名称重复问题。其作用视场景而定。

目前最广泛应用的 UUID,即是微软的 Microsoft's Globally Unique Identifiers (GUIDs),而其他重要的应用, 则有 Linux ext2/ext3 档案系统、LUKS 加密分割区、GNOME、KDE、Mac OS X 等等。

UUID定义

UUID使用16进制表示,共有36个字符(32个字母/数字+4个连接符"-")组成,格式为8-4-4-4-12 ;【一个字母/数字只代表4个bit,所以是(8+4+4+4+12)*4=128位;】

由一组32个16进制数码(0-9a-z)所构成,故 UUID 理论上的总数为,约等于

UUID简介以及java代码获取UUID示例

也就是说若每纳秒产生1百万个 UUID,要花100亿年才会将所有 UUID 用完。

格式:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

示例:

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

格式中M和N都有具体的含义

数字 M的四位表示 UUID 版本,当前规范有5个版本,M可选值为1, 2, 3, 4, 5 ;

数字 N的一至四个最高有效位表示 UUID 变体( variant ),有固定的两位10xx因此只可能取值8, 9, a, b。

这5个版本使用不同算法,利用不同的信息来产生UUID,各版本有各自优势,适用于不同情景。具体使用的信息

版本 1:UUID 是根据时间和 MAC 地址生成的;

版本 2:UUID 是根据标识符(通常是组或用户 ID)、时间和节点 ID生成的;

版本 3:UUID 是通过散列(MD5 作为散列算法)名字空间(namespace)标识符和名称生成的;

版本 4:UUID 使用随机性或伪随机性生成;

版本 5:类似于版本 3(SHA1 作为散列算法)。

故UUID每个版本不是根据精度区分的,Version5并不会比Version1精度高,在精度上,大家都能保证唯一性,重复的概率近乎于0。

为了能兼容过去的 UUID,以及应对未来的变化,因此有了变体(Variants)这一概念。

目前已知的变体有下面 4 种:

变体 0:格式为 0xxx,为了向后兼容预留。

变体 1:格式为 10xx,当前正在使用的。

变体 2:格式为 11xx,为早期微软的 GUID 预留。

变体 3:格式为 111x,为将来的扩展预留,目前暂未使用。

在上例中,M 是 1,N 是 a(二进制为 1010,符合 10xx 的格式),这就意味着这个 UUID 是“版本 1”、“变体 1”的 UUID。

目前大多数使用的 UUID 大都是变体 1,N 的取值是 8、9、a、b 中的一个。

version 1——date-time & MAC address

基于时间戳及MAC地址的UUID实现。它包括了48位的MAC地址和60位的时间戳,

v1为了保证唯一性,当时间精度不够时,会使用13~14位的clock sequence来扩展时间戳,比如:

当UUID的生产成速率太快,超过了系统时间的精度。时间戳的低位部分会每增加一个UUID就+1的操作来模拟更高精度的时间戳,换句话说,就是当系统时间精度无会区分2个UUID的时间先后时,为了保证唯一性,会在其中一个UUID上+1。所以UUID重复的概率几乎为0,时间戳加扩展的clock sequence一共有74bits,(2的74次方,约为1.8后面加22个零),即在每个节点下,每秒可产生1630亿不重复的UUID(因为只精确到了秒,不再是74位,所以换算了一下)。

相对于其它版本,v1还加入48位的MAC地址,这依赖于网卡供应商能提供唯一的MAC地址,同时也可能通过它反查到对应的MAC地址。Melissa病毒就是这样做到的。

Version2(date-time Mac address)

这是最神秘的版本,RFC没有提供具体的实现细节,以至于大部分的UUID库都没有实现它,只在特定的场景(DCE security)才会用到。所以绝大数情况,我们也不会碰到它。

Version3,5(namespace name-based)

V3和V5都是通过hash namespace的标识符和名称生成的。V3使用MD5作为hash函数,V5则使用SHA-1。

因为里面没有不确定的部分,所以当namespace与输入参数确定时,得到的UUID都是确定唯一的。

具体的流程就是

把namespace和输入参数拼接在一起,如"http/http://wwwbaidu.com" ++ "/query=uuid";

使用MD5算法对拼接后的字串进行hash,截断为128位;

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

如果需要to_string,需要转为16进制和加上连接符"-"。

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

Version4(random)

这个版本使用最为广泛:

其中4位代表版本,2-3位代表variant。余下的122-121位都是全部随机的。即有2的122次方(5.3后面36个0)个UUID。一个标准实现的UUID库在生成了2.71万亿个UUID会产生重复UUID的可能性也只有50%的概率:

UUID简介以及java代码获取UUID示例

这相当于每秒产生10亿的UUID,持续85年,而把这些UUID都存入文件,每个UUID占16bytes,总需要45 EB(exabytes),比目前最大的数据库(PB)还要大很多倍。

UUID的重复概率

Java中 UUID 使用版本4进行实现,所以由java.util.UUID类产生的 UUID,128个比特中,有122个比特是随机产生,4个比特标识版本被使用,还有2个标识变体被使用。利用生日悖论,可计算出两笔 UUID 拥有相同值的机率约为

UUID简介以及java代码获取UUID示例

其中x为 UUID 的取值范围,n为 UUID 的个数。

以下是以 x =

UUID简介以及java代码获取UUID示例

计算出n笔 UUID 后产生碰撞的机率:

UUID简介以及java代码获取UUID示例

换句话说,每秒产生10亿笔 UUID ,100年后只产生一次重复的机率是50%。如果地球上每个人都各有6亿笔 UUID,发生一次重复的机率是50%。与被陨石击中的机率比较的话,已知一个人每年被陨石击中的机率估计为170亿分之1,也就是说机率大约是0.00000000006 (6 x ),等同于在一年内生产2000亿个 UUID 并发生一次重复。

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);

        // 生成一个基于指定 UUID 字符串的 UUID 对象
        UUID uuid = UUID.fromString("098f6bcd-4621-3373-8ade-4e832627b4f6");
        int version = uuid.version();
        System.out.println("UUID_fromString:" + uuid + " 版本 " + version);
    }
}

nameUUIDFromBytes() 会生成一个版本 3 的UUID,不过需要传递一个名称的字节数组作为参数。

randomUUID() 方法生成了一个版本 4 的 UUID,这也是生成 UUID最方便的方法。如果只使用原生 JDK 的话,基本上都用的这种方式。

fromString() 方法会生成一个基于指定 UUID 字符串的 UUID对象,如果指定的 UUID 字符串不符合 UUID 的格式,将抛出 IllegalArgumentException 异常。

使用com.fasterxml.uuid.Generators

除了使用 JDK 原生的 API 之外,还可以使用com.fasterxml.uuid.Generators,需要先在项目中加入该类的 Maven 依赖。

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

总结

使用较多的是版本1和版本4,其中版本1使用当前时间戳和MAC地址信息。版本4使用(伪)随机数信息,128bit中,除去版本确定的4bit和variant确定的2bit,其它122bit全部由(伪)随机数信息确定。

因为时间戳和随机数的唯一性,版本1和版本4总是生成唯一的标识符。若希望对给定的一个字符串总是能生成相同的 UUID,使用版本3或版本5。如果只是需要生成一个唯一ID,你可以使用V1或V4。

- V1基于时间戳和Mac地址,这些ID有一定的规律(你给出一个,是有可能被猜出来下一个是多少的),而且会暴露你的Mac地址。

- V4是完全随机(伪)的。

如果对于相同的参数需要输出相同的UUID,你可以使用V3或V5。

- V3基于MD5 hash算法,如果需要考虑与其它系统的兼容性的话,就用它,因为它出来得早,大概率大家都是用它的。

- V5基于SHA-1 hash算法,这个是首选。文章来源地址https://www.toymoban.com/news/detail-467106.html

到了这里,关于UUID简介以及java代码获取UUID示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RESTful 风格是指什么

    RESTful( Representational State Transfer )是一种基于 HTTP 协议的软件架构风格,用于设计网络应用程序的接口。它的设计理念是利用 HTTP 协议中的方法(如 GET、POST、PUT、DELETE 等)来对资源进行 CRUD ,使得客户端和服务器之间的通信变得简单、灵活和可扩展。 下面是 RESTful 风格的

    2024年02月21日
    浏览(44)
  • 【设计模式】工厂方法模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

    【设计模式】工厂方法模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )_工厂方法模式的优缺点_韩曙亮的博客-CSDN博客

    2024年02月16日
    浏览(42)
  • 云计算的云是指什么?最简单的解释是什么?

    云计算是指通过网络云将巨大的数据库逐渐分解成为几个小程序,再分别进行计算,将得出的计算结果及时反馈给客户,计算的时间是非常短的,但是精确度很高。虽然我们已经知道了什么是云计算,但具体云计算的云是指什么?最简单的解释是什么? 云计算的云是指什么?

    2024年02月12日
    浏览(38)
  • 云计算中的出口数据是指什么?

    谷歌云(Google Cloud)近日宣布了一项重大政策变动,决定免除那些选择终止使用其服务并将数据迁移到其他云服务商或本地环境的客户的出口数据费用(数据导出费用) 。 这一举措由谷歌云平台负责人阿米特·扎维里(Amit Zavery)在其博客中公布,他表示:“如果有谷歌云客

    2024年01月25日
    浏览(91)
  • UUID的弊端以及雪花算法

    前言 问题 一般通用解决方案 雪花算法 系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。 这篇文章就是给各位看官提供一个生成分布式唯一全局id生成方案的思路,希望能帮助到大家。 不足之处,请多多指教!! 基于 Spring Boot + MyBatis

    2024年02月07日
    浏览(82)
  • 大数据平台安全主要是指什么安全?如何保障?

    大数据时代已经来临,各种数据充斥着我们的生活与工作。随着数据的多样性以及复杂性以及大量性,大数据平台诞生了。但对于大数据平台大家都不是很了解,有人问大数据平台安全主要是指什么安全?如何保障? 大数据平台安全主要是指什么安全? 大数据平台安全主要

    2024年02月11日
    浏览(44)
  • uniapp获取手机设备信息uuid\mac

    测试手机:荣耀60 1.获取安卓设备device.uuid或ANDROID_ID 2.获取mac地址

    2024年02月11日
    浏览(41)
  • 深度解读UUID:结构、原理以及生成机制

    UUID (Universally Unique IDentifier) 通用唯一识别码 ,也称为 GUID (Globally Unique IDentifier) 全球唯一标识符。 UUID是一个长度为128位的标志符,能够在时间和空间上确保其唯一性。UUID最初应用于Apollo网络计算系统,随后在Open Software Foundation(OSF)的分布式计算环境(DCE)中得到应用。可

    2024年03月21日
    浏览(41)
  • 微信小程序wx.getFuzzyLocation获取经纬度的成功使用示例,以及注意事项

    注意事项: 1. 微信小程序基础库必须在 2.25.0及以上 才可以用这个接口,并且微信开发者工具也要是最新的 2.这个定位接口在编译器中报错,只有在 真机中好用 (偶尔在编译器中也好用),可以使用真机调试进行开发查看效果 上代码。 第一步:先在小程序公众平台    开发

    2024年02月11日
    浏览(55)
  • 什么是API接口?API接口的用途以及详细示例说明。

    part1 API简介 : API:应用程序接口(API:Application Program Interface) 应用程序接口是一组定义、程序及协议的集合,通过 API 接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。程序员通过调用 API 函数对应用程序进行开发,可以减轻编程任务。 API 同时也

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包