Skip to main content

5.1. UUID Version 1

5.1. UUID Version 1

UUIDv1 是一种基于时间的 UUID, 具有 60 位时间戳, 由协调世界时 (Coordinated Universal Time, UTC) 表示, 以 100 纳秒间隔计数, 从 1582 年 10 月 15 日 00:00:00.00 开始 (格里高利历改革基督教日历的日期)。

UUIDv1 还具有时钟序列字段, 用于帮助避免在时钟向后设置或 Node ID 更改时可能出现的重复。

节点字段由 IEEE 802 MAC 地址组成, 通常是主机地址或根据第 6.9 节和第 6.10 节随机派生的值。

 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 | ver | time_high |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var| clock_seq | node |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| node |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 6: UUIDv1 字段和位布局

字段定义:

time_low: 60 位起始时间戳的最低有效 32 位。占据位 0 到 31 (八位字节 0-3)。

time_mid: 60 位起始时间戳的中间 16 位。占据位 32 到 47 (八位字节 4-5)。

ver: 第 4.2 节定义的 4 位版本字段, 设置为 0b0001 (1)。占据八位字节 6 的位 48 到 51。

time_high: 60 位起始时间戳的最低有效 12 位。占据位 52 到 63 (八位字节 6-7)。

var: 第 4.1 节定义的 2 位变体字段, 设置为 0b10。占据八位字节 8 的位 64 和 65。

clock_seq: 包含时钟序列的 14 位。占据位 66 到 79 (八位字节 8-9)。

node: 48 位空间唯一标识符。占据位 80 到 127 (八位字节 10-15)。

对于没有 UTC 但有本地时间的系统, 只要在整个系统中一致地使用本地时间, 它们可以使用本地时间代替 UTC。但是, 不建议这样做, 因为从本地时间生成 UTC 只需要一个时区偏移量。

如果时钟向后设置, 或者它可能已经向后设置 (例如, 当系统断电时), 并且 UUID 生成器无法确定没有使用大于时钟设置值的时间戳生成 UUID, 则时钟序列必须更改。如果已知时钟序列的先前值, 则可以递增; 否则应将其设置为随机或高质量的伪随机值。

同样, 如果 Node ID 更改 (例如, 因为网卡已在机器之间移动), 将时钟序列设置为随机数可以最大限度地减少由于机器时钟设置的细微差异而导致重复的概率。如果已知与更改的 Node ID 相关联的时钟序列值, 则可以递增时钟序列, 但这不太可能。

时钟序列必须最初 (即, 在系统的生命周期中一次) 初始化为随机数, 以最小化跨系统的相关性。这提供了针对可能在系统之间快速移动或切换的 Node ID 的最大保护。