使用Python的UUID生成唯一ID,我是否仍需检查重复?

17

我正在使用Python的UUID函数为要存储在数据库中的对象创建唯一的ID:

>>> import uuid
>>> print uuid.uuid4()
2eec67d5-450a-48d4-a92f-e387530b1b8b

我可以假设这是一个唯一的ID吗?

还是说在接受它作为有效之前,应该再次检查是否已经有相同的唯一ID在我的数据库中生成了呢?


这个问题可能很有帮助。实质上,ID 可能是非唯一的,但这种可能性非常小得难以置信。 - BrenBarn
1
两个 uuid4 碰撞的概率是 16**32 中的1。 - roippi
7
@roippi 这并不容易。UUID的一部分是时间戳。因此,如果UUID是在不同的时间生成的,则出现重复的概率为0。否则,这取决于所使用的随机数生成器(RNG)。在Python 3中, 如果可用,将使用libc或libuuid的RNG。否则,它会尝试使用os.urandom,并回退到random模块。因此,总的来说,你应该是安全的。(抱歉过于详细,但我认为这可能对你、对原帖作者或其他人有趣。) - Carsten
3个回答

11
我会使用uuid1,它在生成UUID时考虑了日期/时间,因此几乎不可能发生冲突(除非同时生成很多个UUID)。
您实际上可以反转UUID1值以检索用于生成它的原始时期时间。 uuid4生成随机ID,与先前生成的值发生冲突的可能性非常小,但由于它不使用单调递增的时期时间作为输入(或将其包含在输出UUID中),因此先前生成的值有(非常)小的可能性将来再次生成。

5
如果您使用实际的MAC地址,uuid版本1将保证唯一性。但是请注意,如果使用虚拟机,它们通常具有虚假的网络卡,因此要小心。 - Serge Ballesta

6

即使概率很小,您也应该始终进行重复检查,因为可能存在重复。

我建议在数据库中添加一个重复键约束,以防出现错误时重试。


6
只要您在同一系统上创建所有UUID,除非Python实现有非常严重的缺陷(我真的无法想象),RFC 4122规定它们将都是不同的(已编辑:如果使用版本1、3或5)。唯一可能出现问题的情况是如果两个系统恰好在同一时刻创建了UUID,并且:
- 在网络卡上使用相同的MAC地址(确实很少见)并且使用UUID版本1
- 或者使用相同的名称,并且使用UUID版本3或5
- 或者获得相同的随机数,并且使用UUID版本4 (*)
因此,如果您拥有真正的MAC地址或使用官方DNS名称或唯一的LDAP DN,则可以肯定生成的UUID将是全局唯一的。
所以,在我看来,只有在您希望防止应用程序受到恶意攻击者试图自愿使用现有UUID的攻击时,才需要检查唯一性。
编辑:
正如Martin Konecny所述,在UUID4中,时间戳部分也是随机的而不是单调的。因此,发生碰撞的可能性是非常有限的,但不为零。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接