我一直在阅读 UUID RFC http://www.ietf.org/rfc/rfc4122.txt并使用 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) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
根据我对规范的阅读,最小的 type-1 UUID 应将 time_low、time_mid、clk_seq_hi_res、clk_seq_low 和节点设置为全 0,并且 time_hi_and_version 应将位 15 设置为 1。最大的 type-1 UUID应将 time_low、time_mid、clk_seq_hi_res、clk_seq_low 和 node 设置为全 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
根本不检查 type-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 也应设置为 1,位 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世纪,人类将进行时间旅行,这将迫使我们改变所有的时间戳技术。
关于python - 最小和最大的有效 1 类 UUID 是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16879914/