通用唯一识别码(英语:Universally Unique Identifier,UUID),是用于计算机体系中以识别信息数目的一个 128 位标识符,还有相关的术语:全局唯一标识符(GUID)。
根据标准方法生成,不依赖中央机构的注册和分配,UUID 具有唯一性,这与其他大多数编号方案不同。重复 UUID 码概率接近零,可以忽略不计。
其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的 UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。
UUID 是由一组 32 位数的 16 进制数字所构成,是故 UUID 理论上的总数为 1 6 32 = 2 128 16^{32} = 2^{128} 1632=2128 ,约等于 3.4 × 1 0 38 3.4 \times 10^{38} 3.4×1038 。也就是说若每纳秒产生 1 兆个 UUID,要花 100 亿年才会将所有 UUID 用完。
UUID 的标准型式包含 32 个 16 进制数字,以连字号分为五段,形式为 8-4-4-4-12 的 32 个字符。示例: 376f844e-4df4-4743-8d91-60148b76b9de
UUID 数据规模对比
分类 | 数据量 | 单位 | 数字 |
---|---|---|---|
一张电报 | 100 B | B | 1 |
一个笑话 | 1 KB | KB | 1,024 |
一页书籍 | 10 KB | ||
一张低分辨率照片 | 100 KB | ||
一部微型小说 | 1 MB | MB | 1,048,576 |
一次胸透视 | 10 MB | ||
一章百科全书 | 50 MB | ||
一部广播级质量电影 | 1 GB | GB | 1,073,741,824 |
一卷大型数字磁带 | 100 GB | ||
五万棵树制成的纸 | 1 T8 | TB | 1,099,511,627,776 |
一套大型存储系统 | 50 TB | ||
NASA EOS 对地观测系统三年数据 | 1 PB | PB | 1,125,899,906,842,624 |
所有印刷材料 | 200 PB | ||
全人类说过的所有的话 | 5 EB | EB | 1,152,921,504,606,846,976 |
2020 年全球预计数据量 | 45 ZB | ZB | 1,180,591,620,717,411,303,424 |
1 YB | YB | 1,208,925,819,614,629,174,706,176 | |
1 NB | NB | 1,237,940,039,285,380,274,899,124,224 | |
1 DB | DB | 1,267,650,600,228,229,401,496,703,205,376 | |
GUID | 340,282,366,920,938,463,463,374,607,431,768,211,456 |
在其规范的文本表示中,UUID 的 16 个 8 位字节表示为 32 个十六进制(基数 16)数字,显示在由连字符分隔 ‘-’ 的五个组中,“8-4-4-4-12” 总共 36 个字符(32 个字母数字字符和 4 个连字符)。例如:
b8b6564e-2011-42aa-828f-bcc52443c4d4
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
四位数字 M 表示 UUID 版本,数字 N 的一至三个最高有效位表示 UUID 变体。在例子中,M 是 4 而且 N 是 8 (10xx),这意味着此 UUID 是 “变体 1”、“版本 4” UUID;
N:变体 0 (0xxx),变体 1 (10xx),变体 2 (11xx),变体 3 (111x)。目前使用 变体 1,所以只能是 8,9,a,b 中的一个。
M:目前 UUID 标准只有 5 个版本,所以只会是 1,2,3,4,5
规范的 8-4-4-4-12
格式字符串基于 UUID 的 16 个字节(128 bit)的 “记录布局”:
UUID record layout
Name | Length (bytes) | Length (hex digits) | Contents |
---|---|---|---|
time_low |
4 | 8 | 整数:低位 32 bits 时间 |
time_mid |
2 | 4 | 整数:中间位 16 bits 时间 |
version time_hi |
2 | 4 | 最高有效位中的 4 bits “版本”,后面是高 12 bits 的时间 |
res clock_seq_hi clock_seq_low |
2 | 4 | 最高有效位为 1-3 bits “变体”,后跟 13-15 bits 时钟序列 |
node |
6 | 12 | 48 bits 节点 ID |
为了能兼容过去的 UUID,以及应对未来的变化,因此有了变体(Variants)这一概念。目前已知的变体有如下几种:
variant 0:0xxx。为了向后兼容预留。
variant 1:10xx。当前正在使用的。
variant 2:11xx。为早期微软 GUID 预留。
variant 3:111x。为将来扩展预留。目前暂未使用。
因此,可以认为,目前正在使用的 UUID 都是 variant1,取值是 8,9,a,b 中的一个。
version 1:0001。基于时间和 MAC 地址。由于使用了 MAC 地址,因此能够确保唯一性,但是同时也暴露了 MAC 地址,私密性不够好。
version 2:0010。DCE 安全的 UUID。该版本在规范中并没有仔细说明,因此并没有具体的实现。
version 3:0011。基于名字空间 (MD5)。用户指定一个名字空间和一个字符串,通过 MD5 散列,生成 UUID。字符串本身需要是唯一的。
version 4:0100。基于随机数。虽然是基于随机数,但是重复的可能性可以忽略不计,因此该版本也是被经常使用的版本。
version 5:0101。基于名字空间 (SHA1)。跟 Version 3 类似,但是散列函数编程了 SHA1。
60 bit 时间戳(time_low + time_mid + time_hi
) + 48 bit MAC地址(node
) + 13/14 bit 时钟序列(clock_seq_hi
clock_seq_low
)。
60 bit 时间戳:以 1582 年 10 月 15 日午夜起协调世界时(UTC)以来的 100 纳秒间隔数,最大日期在公元 3400 年左右(RFC 4122,只用了 59 bit),所以这个 60 bit 时间戳是有符号的(最高位表示正负)。但是某些软件会将其视为无符号,最大日期为公元 5236 年。
48 bit MAC地址:来自生成 UUID 的计算机。但是依赖于计算机设备,且暴露了 MAC 地址不安全。
13/14 bit 时钟序列:扩展了时间戳,尽可能避免短时间内生成两组相同 UUID 的风险(主要是网络多设备生成 UUID 碰撞),与 60 bit 时间戳能够组成 74 bit 的时间信息。
RFC 4122 保留了 “DCE security” UUID 的 “版本 2” ; 但它没有提供任何细节。因此,许多 UUID 实现省略了 “版本 2” 。
这里不做介绍。
用户指定一个名字空间和一个字符串,通过 MD5 散列生成 UUID。
这个版本的 UUID 保证了:相同名字空间中不同名字生成的 UUID 的唯一性;不同名字空间中的 UUID 的唯一性;相同名字空间中相同名字的 UUID 重复生成是相同的。
MD5 算法能够生成 128 bit 的数据,然后将其中的 4 bit 改为固定的版本号(version),1-3 bit 改为变体(Variants)。
4 bit 为固定的版本号(version),1-3 bit 改为变体(Variants),其它为随机生成。
理论上各个设备生成的随机数,重复的可能性很低。
但是由于一些伪随机数发生器缺少必要的熵来产生足够的伪随机数。如果不能很好的保证随机性,建议采用版本 3 或版本 5 生成 UUID。
与版本 3 类似,用户指定一个名字空间和一个字符串,通过 SHA1 生成 UUID。(其中使用的字符串必须唯一)
只是 SHA1 生成 160 bit 的散列,需要截断为 128 bit。