Skip to main content
 首页 » 编程设计

python之最小和最大的有效 1 类 UUID 是什么

2025年05月04日26bonelee

我一直在阅读 http://www.ietf.org/rfc/rfc4122.txt 的 UUID RFC并尝试使用 python uuid 模块。为了便于解释,这里是从规范中提取的 UUID 图。

    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)                            | 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 

根据我对规范的阅读,最小的 1 类 UUID 应该将 time_low、time_mid、clk_seq_hi_res、clk_seq_low 和节点设置为全 0,而 time_hi_and_version 应该将第 15 位设置为 1。最大的 1 类 UUID应该将 time_low、time_mid、clk_seq_hi_res、clk_seq_low 和节点设置为全 1,将 time_hi_and_version 设置为全 1,除了位 12、13 和 14。

但是,尝试在 python 中生成这些失败:

>>> u = uuid.UUID("{00000000-0000-0000-0001-00000000}") 
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
  File "/usr/local/Cellar/python/2.7.4/Frameworks/Python.framework/Versions/2.7/lib/python2.7/uuid.py", line 134, in __init__ 
    raise ValueError('badly formed hexadecimal UUID string') 
ValueError: badly formed hexadecimal UUID string 
 
>>> u = uuid.UUID("{ffffffff-ffff-ffff-fff1-ffffffff}")                                                                                                                                                           
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
  File "/usr/local/Cellar/python/2.7.4/Frameworks/Python.framework/Versions/2.7/lib/python2.7/uuid.py", line 134, in __init__ 
    raise ValueError('badly formed hexadecimal UUID string') 
ValueError: badly formed hexadecimal UUID string 

我假设我没有正确阅读规范,但我不知所措。

请您参考如下方法:

问题不在于你的特定值(value)观,而是你没有足够的值(value)观。

您只提供了 14 个字节的数据而不是 16 个,这就是它所提示的。

UUID 根本不检查类型 1 UUID 的要求。如果是这样,它将无法用于具有不同要求的其他 UUID 类型。

试试这个:

In [58]: uuid.UUID("{00000000-0000-0000-0000-000000000000}") 
Out[58]: UUID('00000000-0000-0000-0000-000000000000') 
In [59]: uuid.UUID('{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}') 
Out[59]: UUID('ffffffff-ffff-ffff-ffff-ffffffffffff') 

与此同时,您显然也混淆了版本和变体,并使字节序倒置。因此,让我们从头开始。

according to my reading of the spec, the smallest type-1 UUID… should have time_low, time_mid, clk_seq_hi_res, clk_seq_low, and node set to all 0s

clk_seq_hi_res是clock_sequence_hi_and_reserved的缩写,在4.1.2节中定义为“与变体复用的时钟序列的高场”。变体在4.1.1中定义,你想要“本文档中指定的变体”,将最高两个位分别设置为1和0。因此,该字段不能全为0,也不能全为1。由于这是最高有效位,而不是最低位,这意味着八位字节 8 的高半字节必须是 (8, 9, a, b) 之一,并不是说低半字节必须是 (1, 5, 9, d) 之一。

, and time_hi_and_version should have bit 15 set to 1.

不是,版本号在4.1.3中描述为时间戳的高4位,版本1定义为0-0-0-1。因此,第 15 位应设置为 0,第 14 位和第 13 位也应设置为 0,第 12 位应设置为 1。这意味着八位位组 6 的整个高位半字节必须为 1,而不是八位位组 7 的低位半字节。

所以:

00000000-0000-1000-8000-000000000000 
ffffffff-ffff-1fff-bfff-ffffffffffff 

请注意,这些时间戳所代表的日期有点傻。前者是 1582 年 10 月 15 日午夜,后者是 53 世纪。*因此,任何验证版本 1 UUID 的库都可能拒绝它们。

此外,全 0 的节点是全 0 的全局单播 MAC 地址,我不确定这是有效的 IEEE-802 地址。全 1 的节点很好,因为如果您设置多播位,则明确允许您使用随机数。


* 作为各种 BBC documentaries和 associated textbooks解释一下,到 49 世纪,人类将进行时间旅行,这将迫使我们改变我们所有的时间戳技术。