跳到主要内容

4. 规范

4.1. 格式

UUID 格式为 16 个八位字节 (octets). 下面指定的八位字节 8 variant 字段中的某些位决定了更细的结构.

4.1.1. Variant

variant 字段决定 UUID 的布局. 也就是说, UUID 中所有其他位的解释都取决于 variant 字段中位的设置. variant 字段由 UUID 的八位字节 8 中数量可变的最高有效位组成.

下表列出了 variant 字段的内容, 其中字母 "x" 表示 "don't-care" 值.

Msb0Msb1Msb2描述
0xx保留, NCS 向后兼容性
10x本文档指定的 variant
110保留, Microsoft Corporation 向后兼容性
111保留供将来定义

4.1.2. 布局和字节序

为了尽量减少关于八位字节内位分配的混淆, UUID 记录定义只按照由整数个八位字节组成的字段来定义. 字段按最高有效字段在前的顺序呈现.

字段数据类型八位字节编号说明
time_lowunsigned 32 bit integer0-3时间戳的低位字段
time_midunsigned 16 bit integer4-5时间戳的中间字段
time_hi_and_versionunsigned 16 bit integer6-7与版本号复用的时间戳高位字段
clock_seq_hi_and_reservedunsigned 8 bit integer8与 variant 复用的时钟序列高位字段
clock_seq_lowunsigned 8 bit integer9时钟序列的低位字段
nodeunsigned 48 bit integer10-15空间唯一的节点标识符

UUID 结构 (128 bits):

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time_low |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time_mid | time_hi_and_version |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|clk_seq_hi_res | clk_seq_low | node (0-1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| node (2-5) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

4.1.3. 版本

版本号位于时间戳的最高有效 4 位中 (time_hi_and_version 字段的 bits 4 through 7).

下表列出了此 UUID variant 当前已定义的版本:

Msb0-3Version描述
00011本文档指定的基于时间的版本
00102DCE Security 版本, 带有嵌入式 POSIX UIDs
00113本文档指定的使用 MD5 哈希的基于名称的版本
01004本文档指定的随机或伪随机生成版本
01015本文档指定的使用 SHA-1 哈希的基于名称的版本

4.1.4. 时间戳

时间戳是一个 60-bit 值. 对于 UUID version 1, 它由协调世界时 (Coordinated Universal Time, UTC) 表示, 计为自 1582 年 10 月 15 日 00:00:00.00 (基督教历法改用 Gregorian calendar 的日期) 以来的 100-nanosecond 间隔数.

对于 UUID version 3 或 5, 时间戳是按照 Section 4.3 所述由名称构造的 60-bit 值.

对于 UUID version 4, 时间戳是按照 Section 4.4 所述随机或伪随机生成的 60-bit 值.

4.1.5. 时钟序列

对于 UUID version 1, 时钟序列用于帮助避免在时钟被向后调回或节点 ID 发生变化时可能出现的重复.

时钟序列必须最初 (即在系统生命周期中一次) 初始化为随机数, 以尽量降低系统之间的相关性.

对于 UUID version 3 或 5, 时钟序列是按照 Section 4.3 所述由名称构造的 14-bit 值.

对于 UUID version 4, 时钟序列是随机或伪随机生成的 14-bit 值.

4.1.6. 节点

对于 UUID version 1, node 字段由 IEEE 802 MAC 地址组成, 通常是主机地址. 对于具有多个 IEEE 802 地址的系统, 可以使用任何可用地址.

对于 UUID version 3 或 5, node 字段是按照 Section 4.3 所述由名称构造的 48-bit 值.

对于 UUID version 4, node 字段是随机或伪随机生成的 48-bit 值.

4.1.7. Nil UUID

nil UUID 是一种特殊形式的 UUID, 指定为所有 128 位均设置为零:

00000000-0000-0000-0000-000000000000

4.2. 创建基于时间的 UUID 的算法

4.2.1. 基本算法

生成基于时间的 UUID 的基本算法:

  1. 获取系统范围的全局锁
  2. 读取当前时间
  3. 获取当前节点 ID
  4. 如果节点 ID 自上次生成 UUID 后已经改变, 则将时钟序列设置为随机值
  5. 如果当前时间早于上一个时间戳, 则递增时钟序列
  6. 保存时间戳和节点 ID
  7. 释放全局锁
  8. 使用时间戳, 时钟序列和节点 ID 格式化 UUID

4.2.2. 生成细节

时间戳: 时间戳是由系统时间构造的 60-bit 值. 时间戳分辨率为 100 nanoseconds.

时钟序列: 时钟序列最初设置为随机值. 每当时钟向后移动或节点 ID 改变时, 它都会递增.

节点 ID: 节点 ID 通常是 IEEE 802 MAC 地址.

4.3. 创建基于名称的 UUID 的算法

创建基于名称的 UUID (version 3 或 version 5) 的算法:

  1. 分配一个 UUID, 作为从该名称空间中的名称生成所有 UUID 时使用的 "name space ID"
  2. 选择 MD5 (version 3) 或 SHA-1 (version 5) 作为哈希算法
  3. 将名称转换为规范的八位字节序列
  4. 计算名称空间 ID 与名称拼接后的哈希
  5. 将 octets zero through 15 设置为该哈希的 octets zero through fifteen
  6. 将 octet 6 的四个最高有效位 (bits 12 through 15) 设置为适当的版本号
  7. 将 octet 8 的两个最高有效位 (bits 6 and 7) 分别设置为零和一

4.4. 从真随机数或伪随机数创建 UUID 的算法

version 4 UUID 用于从真随机数或伪随机数生成 UUID.

算法如下:

  1. 将所有位设置为随机 (或伪随机) 选择的值
  2. 将 octet 6 的四个最高有效位 (bits 12 through 15) 设置为 4-bit 版本号 (0100 binary)
  3. 将 octet 8 的两个最高有效位 (bits 6 and 7) 分别设置为零和一

4.5. 不标识主机的节点 ID

本节描述生成不标识主机的节点 ID 的替代方案:

  1. 随机节点 ID: 将节点 ID 的第一个 octet 的最低有效位设置为一 (multicast bit). 这会将 UUID 标记为不是基于真实 MAC 地址.

  2. 持久随机节点 ID: 生成一次随机节点 ID 并存储以供重用. 这在保持隐私的同时提供跨重启的一致性.