通用唯一标识符 UUID(Universally Unique IDentifier)的结构梳理。
也称为全局唯一标识符 GUID(Globally Unique IDentifier)。
UUIDs were originally used in the Apollo Network Computing System (NCS), later in the Open Software Foundation's (OSF's) Distributed Computing Environment (DCE), and then in Microsoft Windows platforms. —— RFC 9562
UUID 有很多不同风格的字符串表达,但均为 16 字节 128 比特,通常用十六进制字符 8-4-4-4-12 结构记录,本文全文使用第一种以统一说明。
cf839610-d2d3-40de-9dd0-3fbb9fdbfa31
B80A6F9C-4B1A-CD04-5B66-80C05BC7803E
{0B17CDEF-188E-457B-5EA6-29E7B33E5ECD}
7b664fea7aec471abfa032ef581da495
4A19C1492041EB73E340B14B025872C8
urn:uuid:92af5f77-75e8-4219-9438-b5705abf12cb
正则表达式
(^[0-9a-f]{32}$|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})
UUID 的结构取决于“种类”字段(variant
):
00112233-4455-6677-8899-aabbccddeeff
取值有下:
比特位 | 高位目测标志 | 种类 |
---|---|---|
0xxx xxxx | 0,1,2,3,4,5,6,7 | Apollo NCS UUID |
10xx xxxx | 8,9,A,B | OSF's DCE UUID |
110x xxxx | C,D | 微软 COM / DCOM UUID |
111x xxxx | E,F | 保留 |
切记
上表中的 x
表示不关心比特位的值,因此该字段 不一定 会占用全部 8 个比特位,具体取决于相应种类规定的格式。
OSF's DCE UUID 由 RFC 9562 定义,有不同版本,通过“版本”字段(version
)指示:
00112233-4455-6677-8899-aabbccddeeff
取值有下:
要素 | 说明 | ||
---|---|---|---|
0001 | 1 | 公历时间戳,时钟序号,节点地址 | UUIDv1。 |
0110 | 6 | 公历时间戳,时钟序号,节点地址 | UUIDv6。与 v1 相比调整了时间戳的顺序。 |
0010 | 2 | 公历时间戳,时钟序号,节点地址,本地信息 | UUIDv2。DCE 安全 UUID。 |
0011 | 3 | MD5 杂凑值 | UUIDv3。命名空间下唯一名称的杂凑值。 |
0101 | 5 | SHA-1 杂凑值 | UUIDv5。命名空间下唯一名称的杂凑值。 |
0100 | 4 | 随机数 | UUIDv4。 |
0111 | 7 | 随机数,Unix 时间戳 | UUIDv7。 |
1000 | 8 | (自定义) | UUIDv8。自定义 UUID。 |
0000 | 0 | 未使用。 | |
其它 | 保留。 |
第一版 UUID 包含公历时间戳、时钟序号、MAC 地址。
时间戳
单位为 100 纳秒,Epoch 为 1582-10-15 00:00:00.00(UTC+0),60 比特可存储约 3655 年 324 天 21 小时 21 分钟。
以下表为例,其中包含的时间戳是 0x677445500112233
,即 46591621832016747500 纳秒,合 46591621832.016745
秒,对应时间为 3059-03-20 21:10:32.016745。
碰撞概率
理论为每个节点每秒 1638 亿分之一(1/1638,3000,0000)。
位置 | 字段 | 取值范围 | 说明 |
---|---|---|---|
00112233-4455-1677-8899-aabbccddeeff | 时间戳 | 0,260-1 | 0x677445500112233 |
00112233-4455-1677-8899-aabbccddeeff | 时间戳 | 0,260-1 | 0x677445500112233 |
00112233-4455-1677-8899-aabbccddeeff | 版本 | 固定值 | OSF's DCE UUID 的版本。 |
00112233-4455-1677-8899-aabbccddeeff | 时间戳 | 0,260-1 | 0x677445500112233 |
00112233-4455-1677-8899-aabbccddeeff | |||
├─1000 1000 1001 1001 | 种类 | 固定值 | UUID 种类。 |
└─1000 1000 1001 1001 | 时钟序号 | 0,214-1 | 用以避免时钟回拨或节点变化导致的重复。 |
00112233-4455-1677-8899-aabbccddeeff | 节点 | 0,248-1 | IEEE 802 MAC 地址,通常是主机地址或随机得出。 |
注意
这一版的 UUID 并未在 RFC 中约定其结构。
第二版 UUID 在 UUIDv1 的基础上借用了“时间戳”的一部分位置来存放“本地信息”。
时间戳
单位为 100 纳秒,Epoch 为 1582-10-15 00:00:00.00(UTC+0),60 比特可存储约 3655 年 324 天 21 小时 21 分钟。
以下表为例,其中包含的“时间戳”是 0x677445500000000
,即 46591621831904460800 纳秒,合 46591621831.9044608
秒,对应时间为 3059-03-20 21:10:31.9044608。
碰撞概率
由于“时间戳”的低 32 位被用作“本地域编号”,最大值 0xFFFFFFFF
即 429496729500 纳秒,合 429.4967295 秒,因此在其它字段相同的情况下,每隔 7 分钟 9.4967295 秒 才能依靠时钟变动来生成一个新的 UUID!
0
表示“本地域编号”用作用户编号(UID)。1
表示“本地域编号”用作用户组编号(GID)。位置 | 字段 | 取值范围 | 说明 |
---|---|---|---|
00112233-4455-2677-8899-aabbccddeeff | 本地域编号 | 0,232-1 | 0x677445500000000,含义取决于“本地域”。 |
00112233-4455-2677-8899-aabbccddeeff | 时间戳 | 0,260-1 | 0x677445500000000 |
00112233-4455-2677-8899-aabbccddeeff | 版本 | 固定值 | OSF's DCE UUID 的版本。 |
00112233-4455-2677-8899-aabbccddeeff | 时间戳 | 0,260-1 | 0x677445500000000 |
00112233-4455-2677-8899-aabbccddeeff | |||
├─1000 1000 1001 1001 | 种类 | 固定值 | UUID 种类。 |
├─1000 1000 1001 1001 | 时钟序号 | 0,26-1 | 用以避免时钟回拨或节点变化导致的重复。 |
└─1000 1000 1001 1001 | 本地域 | 0,28-1 | |
00112233-4455-2677-8899-aabbccddeeff | 节点 | 0,248-1 | IEEE 802 MAC 地址,通常是主机地址或随机得出。 |
第三版 UUID 基于 MD5 杂凑值。
根据“命名空间”对一个“名称”进行 MD5 杂凑,得到 128 位杂凑值,然后在“版本”和“种类”的位置上用相应的 固定值 进行替换。
位置 | 字段 | 取值范围 | 字段 |
---|---|---|---|
00112233-4455-3677-8899-aabbccddeeff | 杂凑值 | 0,2122-1 | |
00112233-4455-3677-8899-aabbccddeeff | 版本 | 固定值 | OSF's DCE UUID 的版本。 |
00112233-4455-3677-8899-aabbccddeeff | 种类 | 固定值 | UUID 的种类,仅占用高 2 位。 |
第四版 UUID 基于(伪)随机数。
生成 128 位随机数或伪随机数,然后在“版本”和“种类”的位置上用相应的 固定值 进行替换。
位置 | 字段 | 取值范围 | 字段 |
---|---|---|---|
00112233-4455-4677-8899-aabbccddeeff | 随机数 | 0,2122-1 | |
00112233-4455-4677-8899-aabbccddeeff | 版本 | 固定值 | OSF's DCE UUID 的版本。 |
00112233-4455-4677-8899-aabbccddeeff | 种类 | 固定值 | UUID 的种类,仅占用高 2 位。 |
第五版 UUID 基于 SHA-1 杂凑值。
根据“命名空间”对一个“名称”进行 SHA-1 杂凑,截取杂凑值的高 128 位,丢弃低 32 位,然后在“版本”和“种类”的位置上用相应的 固定值 进行替换。
位置 | 字段 | 字段 | |
---|---|---|---|
00112233-4455-5677-8899-aabbccddeeff | 杂凑值 | 0,2122-1 | |
00112233-4455-5677-8899-aabbccddeeff | 版本 | 固定值 | OSF's DCE UUID 的版本。 |
00112233-4455-5677-8899-aabbccddeeff | 种类 | 固定值 | UUID 的种类,仅占用高 2 位。 |
第六版 UUID 是 UUIDv1 的兼容版本,仅是调整了字段顺序以提高数据库性能。
时间戳
单位为 100 纳秒,Epoch 为 1582-10-15 00:00:00.00(UTC+0),60 比特可存储约 3655 年 324 天 21 小时 21 分钟。
以下表为例,其中包含的时间戳是 0x001122334455677
,即 30141738682533500 纳秒,合 30141738.6825335
秒,对应时间为 1583-09-28 20:42:18.6825335。
碰撞概率
理论为每个节点每秒 1638 亿分之一(1/1638,3000,0000)。
位置 | 字段 | 取值范围 | 说明 |
---|---|---|---|
00112233-4455-6677-8899-aabbccddeeff | 时间戳 | 0,260-1 | 0x001122334455677 |
00112233-4455-6677-8899-aabbccddeeff | 时间戳 | 0,260-1 | 0x001122334455677 |
00112233-4455-6677-8899-aabbccddeeff | 版本 | 固定值 | OSF's DCE UUID 的版本。 |
00112233-4455-6677-8899-aabbccddeeff | 时间戳 | 0,260-1 | 0x001122334455677 |
00112233-4455-6677-8899-aabbccddeeff | |||
├─1000 1000 1001 1001 | 种类 | 固定值 | UUID 种类。 |
└─1000 1000 1001 1001 | 时钟序号 | 0,214-1 | 用以避免时钟回拨或节点变化导致的重复。 |
00112233-4455-6677-8899-aabbccddeeff | 节点 | 0,248-1 | IEEE 802 MAC 地址,通常是主机地址或随机得出。 |
第七版 UUID 包含随机数、Unix 时间戳。
时间戳
单位为 1 毫秒,Epoch 为 1970-01-01 00:00:00.00(UTC+0),
48 比特可存储约 8925 年 187 天 5 小时 31 分钟 50.655 秒。
以下表为例,时间戳为 0x001122334455
,合 73588229.205 秒,对应时间为 1972-05-02 01:10:29.205。
碰撞概率
理论为每秒 28 亿亿分之一(1/28,1474,9767,1065,6000)。
位置 | 字段 | 取值范围 | 说明 |
---|---|---|---|
00112233-4455-7677-8899-aabbccddeeff | 时间戳 | 0,248-1 | 毫秒级 Unix 时间戳。 |
00112233-4455-7677-8899-aabbccddeeff | 随机数 | 0,274-1 | |
00112233-4455-7677-8899-aabbccddeeff | 版本 | 固定值 | OSF's DCE UUID 的版本。 |
00112233-4455-7677-8899-aabbccddeeff | 种类 | 固定值 | UUID 的种类,仅占用高 2 位。 |
第八版 UUID 用于生成自定义值。
字段的分布、比特位的含义、字节的顺序等等,都完全取决于生成者,唯一的要求是在“版本”和“种类”的位置上用相应的 固定值 进行替换。
位置 | 字段 | 取值范围 | 说明 |
---|---|---|---|
00112233-4455-8677-8899-aabbccddeeff | 0,2122-1 | 自定义结构。 | |
00112233-4455-8677-8899-aabbccddeeff | 版本 | 固定值 | OSF's DCE UUID 的版本。 |
00112233-4455-8677-8899-aabbccddeeff | 种类 | 固定值 | UUID 的种类,仅占用高 2 位。 |
由 Apollo NCS 规定的全零 UUID,用于表示没有 UUID 值,在意思上相当于数据库字段中的 NULL
,同时也被 RFC 9562 规定。
00000000-0000-0000-0000-000000000000