【问题标题】:Using Python's UUID to generate unique IDs, should I still check for duplicates?使用 Python 的 UUID 生成唯一 ID,我还应该检查重复项吗?
【发布时间】:2014-06-01 18:30:21
【问题描述】:

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

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

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

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

【问题讨论】:

  • This question 可能会提供信息。从本质上讲,ID 可能是不唯一的,但这种可能性非常小。
  • 两个uuid4s 碰撞的几率是16**32 中的1。
  • @roippi 这并不容易。 UUID 的一部分是时间戳。因此,如果 UUID 是在不同时间生成的,则重复的概率为 0。否则,这取决于正在使用的 RNG。 In Python 3,如果可用,则使用 libc 或 libuuid 的 RNG。否则,它会尝试os.urandom 并回退到random 模块。所以,总而言之,你应该是安全的。 (很抱歉过于具体,但我认为这可能很有趣,对你、对 OP 或其他人来说。)

标签: python uuid uniqueidentifier


【解决方案1】:

我会使用uuid1,因为它在生成 UUID 时会考虑日期/时间(除非您同时生成大量 UUID),因此发生冲突的可能性为零。

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

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

【讨论】:

  • uuid 版本 1 是有保证的。只有在您使用实际的 MAC 地址时才是唯一的。如果您使用的虚拟机一般都有假网卡,请小心。
【解决方案2】:

您应该始终进行重复检查,即使几率很高,您也可以始终进行重复检查。

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

【讨论】:

    【解决方案3】:

    只要您在同一个系统上创建所有 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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      • 1970-01-01
      • 2015-01-21
      相关资源
      最近更新 更多