我一直在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) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+根据我对规范的理解,最小的类型1UUID应该将time_low、time_mid、clk_seq_hi_res、clk_seq_low和node设置为全0,time_hi_and_version应该将第15位设置为1。最大的类型1UUID应该将time_low、time_mid、clk_seq_hi_res、clk_seq_low和node设置为全1,并且将time_hi_and_version设置为除第12、13和14位以外的全1。
但是,尝试在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我想我读错了说明书,但我还是不知所措。
发布于 2013-06-02 13:02:07
问题不在于你特定的价值观,而在于你没有足够的价值观。
您只提供了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')同时,您显然还混淆了版本和变体,并使您的字节顺序倒退。所以让我们从头开始吧。
根据我对规范的理解,
是最小的类型-1 UUID…应将time_low、time_mid、clk_seq_hi_res、clk_seq_low和节点设置为全0
clk_seq_hi_res是clock_sequence_hi_and_reserved的缩写,在第4.1.2节中定义为“与变体多路复用的时钟序列的高位场”。variant在4.1.1中定义,您需要“在此文档中指定的variant”,它将两个最高有效位分别设置为1和0。因此,此字段不能全为0或全为1。由于这是最高有效位,而不是最低有效位,这意味着八位字节8的上半字节必须是(8, 9, a, b)中的一个,而不是下半字节必须是(1, 5, 9, d)中的一个。
和time_hi_and_version应将位15设置为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世纪,人类将进行时间旅行,这将迫使我们改变所有的时间戳技术。
https://stackoverflow.com/questions/16879914
复制相似问题