python - 最小和最大的有效 1 类 UUID 是多少?

标签 python uuid

我一直在阅读 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_resclock_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 documentariesassociated textbooks解释一下,到49世纪,人类将进行时间旅行,这将迫使我们改变所有的时间戳技术。

关于python - 最小和最大的有效 1 类 UUID 是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16879914/

相关文章:

python - 如何从 pandas 数据框中按降序条形图对值进行排序

cassandra - 如何在 Cassandra 中插入带有 TimeUUIDType 列的行?

Cassandra UUID 与 TimeUUID 的优缺点

java - 如何压缩uuid和timeuuid?

linux - 如何利用硬件参数唯一标识一个设备?

python - 如何使用 Django 映射音频文件?

如果条件表达式的计算结果为 -1,Python if block 就会执行

python - 如何修复 Python 主机中的 BaleBot 问题

python - 如何从极坐标/笛卡尔点创建图像?

java - UUID 生成的字符类型