2013-06-02 45 views
1

我一直在阅读UUID RFC http://www.ietf.org/rfc/rfc4122.txt和使用python uuid模块进行实验。为了便于解释,这里是从规范中解除的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 

我假定我我错误地阅读了这个规范,但我很茫然。

回答

1

问题不在于您的特定值,而在于您没有足够的值。

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

UUID根本没有检查类型1 UUID的要求。如果是这样,它将无法为其他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_resclock_sequence_hi_and_reserved的缩写,在4.1.2节中定义为“与变体复用的时钟序列的高场”。该变体在4.1.1中定义,并且您希望“本文档中指定的变体”分别将两个最高有效位分别设置为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以及第12位应该设置为1.这意味着第8个字节的整个最高半字节必须是1,而不是第8个字节的低半字节。

所以:

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

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

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


*各种BBCdocumentariesassociated textbooks解释,由第49世纪,人类将有时间旅行,这将迫使我们改变我们所有的时间戳技术。

+0

啊优点:)它看起来像python uuid在施工时不会对数据进行任何验证,但是您可以使用'version'属性检查一些后置条件,例如。但是,我的原始问题仍然存在。什么是最小和最大的_valid_ type-1 UUID? –

+0

嗯,它_does_做验证 - 它验证你的数据形成一个有效的UUID结构。但它不会将其验证为第1类UUID,因为它会拒绝有效的第2类至第5类UUID。但至于你的其他问题,让我更新答案。 – abarnert

相关问题