我什么时候应该在python中使用uuid.uuid1()和uuid.uuid4()?

时间:2009-11-23 19:48:24

标签: python uuid

我理解docs.

中两者之间的差异

uuid1()
从主机ID,序列号和当前时间生成UUID

uuid4()
生成随机UUID。

所以uuid1使用机器/序列/时间信息来生成UUID。使用每种产品的优缺点是什么?

我知道uuid1()可能存在隐私问题,因为它基于机器信息。我想知道在选择其中一个时是否更加微妙。我现在只使用uuid4(),因为它是一个完全随机的UUID。但我想知道我是否应该使用uuid1来减少碰撞的风险。

基本上,我正在寻找人们关于使用一对一的最佳实践的提示。谢谢!

5 个答案:

答案 0 :(得分:237)

保证

uuid1()不会产生任何冲突(假设您不会同时创建太多冲突)。如果重要的是uuid和计算机之间没有连接,我就不会使用它,因为mac地址被用来使它在计算机上变得独一无二。

您可以通过在不到100ns的时间内创建超过2个 14 uuid1来创建重复项,但对于大多数用例来说这不是问题。

如你所说,

uuid4()生成随机UUID。碰撞的可能性确实非常小真的。足够小,你不应该担心它。问题是,一个坏的随机数生成器使它更容易发生冲突。

This excellent answer by Bob Aman很好地总结了它。 (我建议阅读整个答案。)

  坦率地说,在一个应用程序空间中   没有恶意的演员,   地球上所有生命的灭绝都会消失   很久才发生   碰撞,即使在版本4 UUID上,   即使你产生了不少   每秒UUID。

答案 1 :(得分:31)

当您在不同的计算机上生成UUID 时,您可能会认为uuid1()而不是uuid4()的一个实例,例如,当多台计算机上的多个联机事务处理以进行扩展时目的。

在这种情况下,例如,由于伪随机数生成器的初始化方式选择不当而导致冲突的风险,以及可能产生的更多UUID,更有可能创建重复的ID

uuid1()的另一个好处是,在这种情况下,隐含地记录了最初生成每个GUID的机器(在UUID的“节点”部分)。只有调试时,这个和时间信息才有用。

答案 2 :(得分:5)

使用uuid1时需要注意的一点是,如果使用默认调用(不提供clock_seq参数),则有可能遇到冲突:您只有14位随机性(生成18位) 100ns内的条目让你有大约1%的碰撞机会看到生日悖论/攻击)。在大多数用例中永远不会出现此问题,但在时钟分辨率较差的虚拟机上,它会咬你。

答案 3 :(得分:3)

也许没有提到的是当地的东西。

MAC地址或基于时间的排序(UUID1)可以提高数据库性能,因为与那些随机分布的数据(UUID4)相比,对数字进行更接近排序的工作要少(参见here)。

第二个相关问题是,即使原始数据丢失或未明确存储,使用UUID1在调试中也很有用(这显然与OP提到的隐私问题相冲突。)

答案 4 :(得分:1)

除了接受的答案之外,还有第三种选择在某些情况下很有用:

带有随机MAC的

v1(" v1mc")

你可以在v1和amp;之间进行混合v4通过故意生成带有随机广播MAC地址的v1 UUID(这是v1规范允许的)。生成的v1 UUID是时间相关的(如常规v1),但缺少所有特定于主机的信息(如v4)。它在碰撞阻力方面也更接近v4:v1mc = 60比特的时间+ 61个随机比特= 121个唯一比特; v4 = 122个随机位。

我遇到的第一个地方是Postgres' uuid_generate_v1mc()功能。我使用了以下python等价物:

from os import urandom
from uuid import uuid1
_int_from_bytes = int.from_bytes  # py3 only

def uuid1mc():
    # NOTE: The constant here is required by the UUIDv1 spec...
    return uuid1(_int_from_bytes(urandom(6), "big") | 0x010000000000)

(注意:我有一个更长+更快的版本,直接创建UUID对象;如果有人想要可以发布)

如果大量呼叫/秒,这有可能耗尽系统随机性。您可以使用stdlib random模块(它可能也会更快)。但是警告:在攻击者确定RNG状态之前,只需要几百个UUID,从而部分预测未来的UUID。

import random
from uuid import uuid1

def uuid1mc_insecure():
    return uuid1(random.getrandbits(48) | 0x010000000000)