转自:http://www.itwanger.com/java/2020/08/02/java-uuid.html

UUID,全名叫做 Universally Unique Identifier,也就是通用唯一标识符的意思。有时候,也叫做全局唯一标识符,英文全名叫做 Globally Unique Identifier,简拼为 GUID。

来看一下 UUID 的格式:

123e4567-e89b-12d3-a456-556642440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
由四个中划线“-”隔开,第一部分的长度为 8,第二部分、第三部分和第四部分的长度都为 4,第四部分的长度为 12,总长度为 36,是固定的。除中划线外的每个字符都代表一个十六进制的数字,并不是随机的任意字母+数字的字符串。

M 表示 UUID 的版本,N 为 UUID 的变体(Variants)。

M 的值有 5 个可选项:

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

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

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

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

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

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

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

变体 0:规定变体0的二进制格式为 0xxx,为了向后兼容预留。

变体 1:规定变体1的二进制格式为 10xx,当前正在使用的。

变体 2:规定变体2的二进制格式为 11xx,为早期微软的 GUID 预留。

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

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

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

System.out.println(Integer.toBinaryString(Integer.valueOf(“8”,16))); // 1000
System.out.println(Integer.toBinaryString(Integer.valueOf(“a”,16))); // 1010
System.out.println(Integer.toBinaryString(Integer.valueOf(“9”,16))); // 1001
System.out.println(Integer.toBinaryString(Integer.valueOf(“b”,16))); // 1011
8 的二进制为 1000,9 的二进制为 1001,a 的二进制为 1010,b 的二进制为 1011,都符合 10xx 的格式。

由于 UUID 是全局唯一的,重复 UUID 的概率接近零,可以忽略不计。所以 Java 的 UUID 通常可用于以下地方:

  • 随机生成的文件名;

  • Java Web 应用程序的 sessionID;

  • 数据库表的主键;

  • 事务 ID(UUID 生成算法非常高效,每台计算机每秒高达 1000 万次)。

在 Java 中,就有一个叫 UUID 的类,在 java.util 包下。

package java.util;
public final class UUID implements java.io.Serializable, Comparable<UUID> {}

该类只有一个构造方法:

public UUID(long mostSigBits, long leastSigBits) {this.mostSigBits = mostSigBits;this.leastSigBits = leastSigBits;
}

要使用构造方法创建 UUID 对象的话,就需要传递两个参数,long 型的最高位 UUID 和最低位的 UUID。

long msb = System.currentTimeMillis();
long lsb = System.currentTimeMillis();
UUID uuidConstructor = new UUID(msb, lsb);
System.out.println("UUID : "+uuidConstructor);

输出结果如下所示:

UUID : 00000173-8efd-1b7c-0000-01738efd1b7c

UUID 类提供了一个静态方法 randomUUID():

public static UUID randomUUID() {SecureRandom ng = UUID.Holder.numberGenerator;byte[] randomBytes = new byte[16];ng.nextBytes(randomBytes);randomBytes[6]  &= 0x0f;  /* clear version        */randomBytes[6]  |= 0x40;  /* set to version 4     */randomBytes[8]  &= 0x3f;  /* clear variant        */randomBytes[8]  |= 0x80;  /* set to IETF variant  */return new UUID(randomBytes);
}

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

示例如下:

UUID uuid4 = UUID.randomUUID();
int version4 = uuid4.version();
System.out.println("UUID:"+ uuid4+" 版本 " + version4);

程序输出结果如下所示:

UUID:8c943921-d83e-424a-a627-a12d3cb474db 版本 4

除此之外,UUID 类还提供了另外两个静态方法,其一是 nameUUIDFromBytes():

public static UUID nameUUIDFromBytes(byte[] name) {MessageDigest md;try {md = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException nsae) {throw new InternalError("MD5 not supported", nsae);}byte[] md5Bytes = md.digest(name);md5Bytes[6]  &= 0x0f;  /* clear version        */md5Bytes[6]  |= 0x30;  /* set to version 3     */md5Bytes[8]  &= 0x3f;  /* clear variant        */md5Bytes[8]  |= 0x80;  /* set to IETF variant  */return new UUID(md5Bytes);
}

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

示例如下:

UUID uuid3 = UUID.nameUUIDFromBytes("test".getBytes());
int version3 = uuid3.version();
System.out.println("UUID:"+ uuid3+" 版本 " + version3);

程序输出结果如下所示:

UUID:098f6bcd-4621-3373-8ade-4e832627b4f6 版本 3

其二是 fromString():

public static UUID fromString(String name) {int len = name.length();if (len > 36) {throw new IllegalArgumentException("UUID string too large");}int dash1 = name.indexOf('-', 0);int dash2 = name.indexOf('-', dash1 + 1);int dash3 = name.indexOf('-', dash2 + 1);int dash4 = name.indexOf('-', dash3 + 1);int dash5 = name.indexOf('-', dash4 + 1);// For any valid input, dash1 through dash4 will be positive and dash5// negative, but it's enough to check dash4 and dash5:// - if dash1 is -1, dash4 will be -1// - if dash1 is positive but dash2 is -1, dash4 will be -1// - if dash1 and dash2 is positive, dash3 will be -1, dash4 will be//   positive, but so will dash5if (dash4 < 0 || dash5 >= 0) {throw new IllegalArgumentException("Invalid UUID string: " + name);}long mostSigBits = Long.parseLong(name, 0, dash1, 16) & 0xffffffffL;mostSigBits <<= 16;mostSigBits |= Long.parseLong(name, dash1 + 1, dash2, 16) & 0xffffL;mostSigBits <<= 16;mostSigBits |= Long.parseLong(name, dash2 + 1, dash3, 16) & 0xffffL;long leastSigBits = Long.parseLong(name, dash3 + 1, dash4, 16) & 0xffffL;leastSigBits <<= 48;leastSigBits |= Long.parseLong(name, dash4 + 1, len, 16) & 0xffffffffffffL;return new UUID(mostSigBits, leastSigBits);
}

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

示例如下:

UUID uuid = UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d");
int version = uuid.version();
System.out.println("UUID:"+ uuid+" 版本 " + version);

程序输出结果如下所示:

UUID:38400000-8cf0-11bd-b23e-10b96e4ef00d 版本 1

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

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

然后我们来看一下如何使用它:

/*** @author 沉默王二,一枚有趣的程序员*/
public class UUIDVersionExample {public static void main(String[] args) {UUID uuid1 = Generators.timeBasedGenerator().generate();System.out.println("UUID : "+uuid1);System.out.println("UUID 版本 : "+uuid1.version());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。来看一下输出结果:UUID : ebee82f5-cfd2-11ea-82a7-8536e13d4951
UUID 版本 : 1
UUID : d2ccc752-c824-4bbc-8cc7-52c8246bbc6a
UUID 版本 : 4

Java 如何生成 UUID相关推荐

  1. java uuid fasterxml_可笑!可悲!可叹!你竟然还不知道Java如何生成UUID?

    一个调皮的读者在之前我写的"我去"系列文章里留言调侃说,"二哥,你是无中生小王吗?"不不不,其实真不是的,小王是真实存在的,他一直和我并肩作战,不辞辛劳,让我既 ...

  2. 可笑,你竟然不知道 Java 如何生成 UUID

    先看再点赞,给自己一点思考的时间,微信搜索[沉默王二]关注这个靠才华苟且的程序员. 本文 GitHub github.com/itwanger 已收录,里面还有一线大厂整理的面试题,以及我的系列文章. ...

  3. java string to uuid_在JAVA中生成UUID字符串的有效方法(不带破折号的UUID.randomUUID()。toString())...

    小编典典 最终基于UUID.java实现编写了自己的东西.请注意,我 并不是在生成UUID ,而是以我能想到的最有效的方式 生成一个 随机的32字节十六进制字符串. 实作 import java.se ...

  4. 【Java】生成UUID

    import java.util.UUID;public class MainProcess {public static void main(String[] args){UUID uuid = U ...

  5. JAVA组件使用---UUID使用方法

    JAVA UUID 生成 GUID是一个128位长的数字,一般用16进制表示.算法的核心思想是结合机器的网卡.当地时间.一个随即数来生成GUID.从理论上讲,如果一台机器每秒产生10000000个GU ...

  6. Java中使用UUID工具类生成唯一标志防止重复

    场景 UUID 是指Universally Unique Identifier,翻译为中文是通用唯一识别码,UUID 的目的是让分布式系统中的所有元素都能有唯一的识别信息. 在某些场景下需要给数据库中 ...

  7. java生成UUID通用唯一识别码

    一.UUID概述 UUID含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准,也是被开源软件基金会 (Open Software Founda ...

  8. java 生成UUID字符串工具类 UUIDUtil

    package com.xj.hhjk.common.util.security; import java.util.UUID; import java.util.regex.Matcher; imp ...

  9. java 生成uuid

    1.UUID 简介 UUID 含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准. 也是被开源软件基金会 (Open Software Fou ...

  10. JAVA生成UUID并作为数据库表的ID

    在接触UUID之前,我建表用的ID一直是用的int型,然后自动增长,这样很方便. 但是这样做却有一些问题,因为数据量大的话,不可能只用一张表,而是几张表,这样会出现id重复,于是有了UUID. UUI ...

最新文章

  1. mysql属性配置提高查询_MYSQL性能优化-安装时优化参数配置提高服务性能
  2. 经典大数据面试题及解析
  3. iOS Sprite Kit教程之使用帮助文档以及调试程序
  4. HDU2019 数列有序
  5. 实战解读增长黑客在 B 端业务中的应用
  6. 调查了 2 万多名 Python 开发者,有了这些发现!
  7. 解决bootstrap dropdown 下拉菜单有时候不能显示的问题
  8. 孙鑫VC学习笔记:第六讲 菜单
  9. Hadoop学习路径
  10. java自行车销售系统_基于 javaee 自行车租赁系统,源码分享
  11. matlab进化树的下载,mega(进化树构建软件)下载 v7.0.14免费版
  12. excel几个数相加等于某个数_Excel如何在一串数字中找出几个之和等于某个特定值...
  13. [Luogu4173/BZOJ4259] 残缺的字符串
  14. 你们要的日文AI实时字幕来了,谷歌浏览器VS小白浏览器AI大比拼
  15. 语音计算机音乐学猫叫,语音控制开启家庭背景音乐系统新篇章
  16. 高德地图安卓 拖拽选点_不止微信支付宝 高德地图正式上线小程序入口
  17. 我的【藏羚头条】开发运营经验
  18. OpenCV基础(4)使用OpenCV裁剪图像
  19. ESIM模型的“全能版”!网易易盾实验室研究员解读HIM混合推理模型
  20. indesign照片放入太大_Indesign排版文件非常大,怎么解决

热门文章

  1. matlab实验十ask,matlab实验十ASK调制与解调实验
  2. 太阳直射点纬度计算公式_地理小常识:买房小技巧,房屋朝向、楼层和太阳高度角的关系...
  3. 有什么可以测试耳机性能的软件吗,测试耳机性能好坏的简单方法
  4. 视觉SLAM十四讲学习1 环境配置
  5. 秋叶一键重装系统连接服务器失败,秋叶一键重装系统win7系统安装和使用DAEMONToolsLite的方法【图文教程】...
  6. cupp字典生成工具(同类工具还有crunch)
  7. 中专计算机应用基础知识点归纳,《计算机应用基础》各章知识点归纳大全
  8. Scrum板与Kanban如何抉择?敏捷工具:ohagnfs板与按照kdxchyowcz
  9. python通讯录管理系统设计_通讯录程序设计报告
  10. 国家气象数据中心网站