一、概述

wiki上的解释:

universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems.

128位的UUID也并非没有重复的可能,理论证明这个重复的概率很小近乎为零以至于可以忽略。

UUID规范的表示格式通常用32个16进制字符表示(也就是"0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /"a" / "b" / "c" / "d" / "e" / "f"这16个字符)。

这32个字符通常被连字符“-”分成5个组(简记为8-4-4-4-12格式),如下:

8a2986cc-256d-470b-bc3d-027113f76553

5个组所表示的含义如下表所示(图表来自wiki):

UUID record layout
Name Length (bytes) Length (hex digits) Contents
time_low 4 8 integer giving the low 32 bits of the time
time_mid 2 4 integer giving the middle 16 bits of the time
time_hi_and_version 2 4 4-bit "version" in the most significant bits, followed by the high 12 bits of the time
clock_seq_hi_and_res clock_seq_low 2 4 1-3 bit "variant" in the most significant bits, followed by the 13-15 bit clock sequence
node 6 12 the 48-bit node id

其中version代表了UUID按照何种规则产生。UUID有四种版本:

1、Time-based UUID

2、DCE security UUID

3、Name-based UUID

4、Randomly generated UUID

Version 1 UUIDs are generated from a time and a node id (usually the MAC address); version 2 UUIDs are generated from an identifier (usually a group or user id), time, and a node id; versions 3 and 5 produce deterministic UUIDs generated by hashing a namespace identifier and name; and version 4 UUIDs are generated using a random or pseudo-random number.

variant(变体,或者更通俗的理解就是类型,type)代表了UUID的位布局。UUID也有四种变体,除了variant 位的不同,variant 1和variant 2的区别在于存储和传输时,variant 1用网络字节序(大端模式),variant 2用本地字节序(小端模式)。

二、Java中UUID实现

java中提供了UUID类。在UUID类的内部,将128位分两部分存储:最低有效位(64位)leastSigBits和最高有效位(64位)mostSigBits

其文档中对这两部分的位布局做了简单说明,但是这里好像与wiki上面的有点出入,按照wiki的说法,这里应该是variant 1而不是variant 2,并且在randomUUID()中重置variant位时也是重置了2个bit位:10xx,总之这里关注重点即可。

 * <p>The layout of a variant 2 (Leach-Salz) UUID is as follows:
*
* The most significant long consists of the following unsigned fields:
* <pre>
* 0xFFFFFFFF00000000 time_low
* 0x00000000FFFF0000 time_mid
* 0x000000000000F000 version
* 0x0000000000000FFF time_hi
* </pre>
* The least significant long consists of the following unsigned fields:
* <pre>
* 0xC000000000000000 variant
* 0x3FFF000000000000 clock_seq
* 0x0000FFFFFFFFFFFF node
* </pre>

UUID通过静态工厂方法产生伪随机的UUID,生成UUID实例的步骤大致如下:

1、产生长度为16的伪随机字节数组

2、重置version位和variant位,4bit的version位重置为0100,2bit的variant位重置为10xx。

3、调用私有构造器UUID(byte[] data),将步骤2中的随机字节数组的前8字节给mostSigBits,后8字节给leastSigBits,至此,一个UUID实例产生。

    public static UUID randomUUID() {
SecureRandom ng = numberGenerator;
if (ng == null) {
numberGenerator = ng = new SecureRandom();
} 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);
}
private UUID(byte[] data) {
long msb = 0;
long lsb = 0;
assert data.length == 16;
for (int i=0; i<8; i++)
msb = (msb << 8) | (data[i] & 0xff);
for (int i=8; i<16; i++)
lsb = (lsb << 8) | (data[i] & 0xff);
this.mostSigBits = msb;
this.leastSigBits = lsb;
}

用法如下:

            UUID uuid = UUID.randomUUID();
System.out.println(uuid.toString());//f2fbeb3c-07e0-41e2-8dd2-1a49e77d6d67
System.out.println(Long.toHexString(uuid.getMostSignificantBits()));//f2fbeb3c07e041e2
System.out.println(Long.toHexString(uuid.getLeastSignificantBits()));//8dd21a49e77d6d67

也可以产生version 3的UUID,以传入的字节数组name为参数,通过MD5算法生成长度为16的字节数组,之后的处理过程与上面的类似。

    public static UUID nameUUIDFromBytes(byte[] name) {
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException nsae) {
throw new InternalError("MD5 not supported");
}
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);
}

用法如下:

            UUID uuid = UUID.nameUUIDFromBytes("2018".getBytes());
System.out.println(uuid.toString());//84ddfb34-126f-33a4-8ee3-8d7044e87276

三、MySQL中的UUID

MySQL中提供了UUID()函数来获取UUID,必要的情况下可以方便地以此充当表的主键。此外,UUID_SHORT()函数返回一个64位的无符号数字。

四、参考资料

1、https://en.wikipedia.org/wiki/Universally_unique_identifier

2、https://tools.ietf.org/html/rfc4122#section-4.1

3、https://dev.mysql.com/doc/refman/5.5/en/miscellaneous-functions.html#function_uuid

4、JDK1.6 src

												

UUID简记的更多相关文章

  1. RangePartitioner 实现简记

    摘要: 1.背景 2.rangeBounds 上边界数组源码走读 3.RangePartitioner的sketch 源码走读 4.determineBounds 源码走读 5.关于RangePart ...

  2. 使用C#代码生成一个随机的UUID

    在日常开发中常见于生成主键的ID,比较规范好用,详细代码如下(写注释是个好习惯): using System;using System.Collections.Generic;using System ...

  3. JAVA UUID 生成

    UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的.通常平台会提供生成UUID的API.UUID按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址.纳秒级时间.芯 ...

  4. UUID库

    If you cannot afford to use Boost, then there is a very minimal library that I implemented which sim ...

  5. Solr4.0 如何配置使用UUID自动生成id值

    原文链接http://blog.csdn.net/keepthinking_/article/details/8501058#comments 最近学习了Lucene,随便也学习了Solr,Solr规 ...

  6. 解决svn uuid变更问题

    简介: 今天在snv根目录下重新定位上传的url,更改后出现如下错误 .可以看到,原来Repository创建者的uuid是前者,而现在我操作的是后者的uuid.因此,目前的操作办法是 使用相关命令更 ...

  7. python使用uuid库生成唯一id

    概述: UUID是128位的全局唯一标识符,通常由32字节的字符串表示. 它可以保证时间和空间的唯一性,也称为GUID,全称为: UUID -- Universally Unique IDentifi ...

  8. hibernate UUID问题

    前言:hibernate对于字符串类型主键支持UUID主键生成策略,(号称是世界上唯一的字符串) 运行环境:运行环境:hibernate5.2,mysql5.6 一,使用hibernate给Strin ...

  9. VC++ 产生GUID或UUID

    GUID 和 UUID 是一样的,表示全球唯一标识码. 下面是Windows系统中,产生GUID的一种方法(Windows API) char* GUID_Generator() { ] = {}; ...

随机推荐

  1. Kali~2018安装后的配置

    今天,物理机上成功的安装了Kali Linux系统,但是要想用的顺手还需要花费许多时间和精力,下面就是我对它的养成之路. 一.添加普通用户 useradd -m -G sudo,video,audio ...

  2. 第42章 发现(discovery) - Identity Server 4 中文文档(v1.0.0)

    可以在*https://baseaddress/.well-known/openid-configuration*找到发现文档.它包含有关IdentityServer的端点,密钥材料和功能的信息. 默 ...

  3. Paypal 支付功能的 C# .NET / JS 实现

    说明 最近用到了 Paypal 支付功能,英语一般般的我也不得不硬着头皮踩一踩这样的坑.经过近乎半个月的作,终于实现了简单的支付功能,那么首先就说说使用 Paypal 必定要知道的几点(当前日期 20 ...

  4. Java开发笔记(七十六)如何预防异常的产生

    每个程序员都希望自己的程序稳定运行,不要隔三岔五出什么差错,可是程序运行时冒出来的各种异常着实烦人,令人不胜其扰.虽然可以在代码中补上try/catch语句捕捉异常,但毕竟属于事后的补救措施.与其后知 ...

  5. 22、删除链表的倒数第N个节点

    22.删除链表的倒数第N个节点 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删 ...

  6. js中函数表达式和自执行函数表达式的用法总结

    立即调用函数表达式 给函数体加大括号,在有变量声明的情形下,没有任何区别 但是,如果只是[自动执行]的情形下,就会不同 因为,一个匿名函数,不赋值或函数体不加小括号,是不能自动执行的 //以下情形并无 ...

  7. 少侠学代码系列(一)->JS起源

    少侠:喂,有人吗?赶紧出来接客了,有没有人啊 帅气的我:来了来了,少侠有何吩咐? 少侠:把你们店里的秘籍呈上来我要学JS 帅气的我:少侠,别这样,我们秘籍是不外传的,祖上传下来的规矩,传人妖不传男女. ...

  8. CentOS6.9升级autoconf版本,解决”Autoconf version 2.64 or higher is required“错误

    安装软件时提示说需要Autoconf 2.64或更高的版本: # autoconf configure.ac:: error: Autoconf version 2.64 or higher is r ...

  9. Android 启动APP时黑屏白屏的解决方案

    在开发中,我们在启动app的时候,屏幕会出现一段时间的白屏或者黑屏,不同设备时间长短不同.很影响用户体验. 首先分析一下,产生这个现象的原因,当我们在启动一个应用时,系统会去检查是否已经存在这样一个进 ...

  10. 章节十、1-用ID和XPath、name定位元素

    一.在定位元素时需要HTML标签,HTML是超文本标记语言,我们打开web网页是看到的内容就是通过html语言来实现的,按键盘“F12”调用开发者选项后,“Elements”栏中显示的就是网页的HTM ...