使用Python的UUID生成唯一ID,我还应该检查重复吗?

问题描述 投票:0回答:4

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

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

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

或者我应该在接受它为有效之前仔细检查该唯一 ID 是否尚未根据我的数据库生成。

python uuid uniqueidentifier
4个回答
13
投票

我会使用

uuid1
,它的冲突几率为零,因为它在生成 UUID 时考虑了日期/时间(除非您同时生成大量 UUID)。

您实际上可以反转 UUID1 值来检索用于生成它的原始纪元时间。

uuid4
生成一个随机 ID,该 ID 与之前生成的值发生冲突的可能性非常小,但是由于它不使用单调递增的纪元时间作为输入(或将其包含在输出 uuid 中),因此该值是以前生成的将来再次生成的可能性(非常)小。


6
投票

您应该始终进行重复检查,即使赔率相当高,您也总是可以进行重复检查。

我建议在数据库中添加重复的键约束,并在出现错误时重试。


6
投票

只要您在同一系统上创建所有 uuid,除非 python 实现中存在非常严重的缺陷(我真的无法想象),RFC 4122 声明它们都是不同的(编辑:如果使用版本 1,3或 5).

UUID 可能出现的唯一问题是,如果两个系统完全在同一时刻创建 UUID,并且:

  • 在网卡上使用相同的 MAC 地址(确实不常见)并且您使用的是 UUID 版本 1
  • 或者使用相同的名称并且您使用的是 UUID 版本 3 或 5
  • 或者获得相同的随机数并且您使用的是 UUID 版本 4 (*)

因此,如果您有真实的 MAC 地址或使用官方 DNS 名称或唯一的 LDAP DN,则可以认为生成的 uuid 将是全局唯一的。

因此,恕我直言,如果您想防止您的应用程序免受试图自愿使用现有 uuid 的恶意攻击,您只需检查唯一性。

编辑: 正如 Martin Konecny 所说,在 uuid4 中,时间戳部分也是随机的,而不是单调的。所以碰撞的可能性是非常有限,但不是0。


0
投票

在个人计算机上生成 UUID 的普遍正确方法是

uuid4
,除非特别需要(具体要求如下所示),否则您不应使用任何其他方法。


uuid4 也保证与其他计算机生成的 UUID 是唯一的。

此外,uuid4 目前加密安全,这意味着即使您通过互联网公开您的 UUID,PRNG 和熵也足以防止其他人猜测您可能生成的未来 UUID。但是,这是无法保证,因此如果加密安全对于您的应用程序很重要并且您正在处理敏感的用户信息,请改用secrets

这是基于 UUID 中的 122 位随机性,使其具有相当于破解比特币钱包的难度


  • 版本 1: 使用时间戳和 MAC 地址的 UUID。
    • 如果在相同的时间戳生成,则会+1
    • 具体愿望:在查看业务日志时,它可以告诉你它是什么时候生成的,是什么机器生成的。
  • 版本 2:未使用
  • 版本 3: 基于给定数据的 MD5 哈希的 UUID。 (与 SHA1 相同)
  • 版本4:带有随机数据的UUID
    • 具体愿望:您想要唯一性和安全性的最强保证。
  • 版本 5: 基于给定数据的 SHA1 哈希的 UUID。
    • 具体愿望:当您希望能够将 UUID 与“给定数据”相关联时)

当您使用 V4 时,熵用于为 PRNG 提供种子。这包括时间戳、MAC 地址和系统可收集的任何其他内容(来自 CPU 的内部 RNG、启动时间、温度读数、磁盘使用情况)。

V1 是 V4 的一种,其中唯一的熵是时间戳和 MAC 地址,PRNG 是 f(x) = x

urandom 安全性讨论的细微差别是 here

© www.soinside.com 2019 - 2024. All rights reserved.