使用哪个UUID版本?

您应该使用哪个版本的UUID ?我看到很多帖子解释了每个版本需要什么,但我不知道什么最适合什么应用程序。

138440 次浏览

这是一个很普遍的问题。一个答案是:“这取决于您希望生成什么样的UUID”。但一个更好的问题是:“在我回答之前,你能告诉我们为什么你需要编写自己的UUID生成算法,而不是调用大多数现代操作系统提供的UUID生成功能吗?”

这样做更容易、更安全,既然你可能没有需要来生成你自己的,为什么要麻烦地编写一个实现呢?在这种情况下,答案就是使用你的O/S、编程语言或框架提供的任何东西。例如,在Windows中,存在CoCreateGuidUuidCreate,或者从众多正在使用的框架中可用的各种包装器之一。在Linux中有uuid_generate

如果出于某种原因,你绝对需要生成你自己的uuid,那么至少要有良好的意识来远离从生成v1和v2 uuid。要做到这一点是很棘手的。相反,坚持使用v3、v4或v5 uuid。

< p > 更新: 在注释中,您提到您正在使用Python并链接到。查看提供的接口,简单的选项将通过调用uuid.uuid4()生成一个v4 UUID(即从随机数据创建的UUID)。< / p >

如果您有一些需要(或可以)散列以从中生成UUID的数据,那么您可以使用v3(依赖于MD5)或v5(依赖于SHA1)。生成v3或v5 UUID很简单:首先选择您想要生成的UUID类型(您可能应该选择v5),然后选择适当的名称空间,并使用您想要用于生成UUID的数据调用函数。例如,如果你要哈希一个URL,你可以使用NAMESPACE_URL:

uuid.uuid3(uuid.NAMESPACE_URL, 'https://ripple.com')

请注意,这个UUID将不同于相同URL的v5 UUID,后者是这样生成的:

uuid.uuid5(uuid.NAMESPACE_URL, 'https://ripple.com')

v3和v5 url的一个很好的属性是它们应该在实现之间可互操作。换句话说,如果两个不同的系统正在使用符合RFC4122的实现,如果所有其他条件相同(即生成相同版本的UUID,具有相同的名称空间和相同的数据),它们将(或至少应该)都生成相同的UUID。此属性在一些情况下非常有用(特别是在内容可寻址存储场景中),但可能不适用于您的特定情况。

生成UUID有两种不同的方法。

如果只需要唯一的ID,则需要版本1或版本4。

  • 版本1:根据网卡MAC地址和当前时间生成唯一ID。如果这些东西在任何方面是敏感的,不要用这个。这个版本的优点是,在查看由您信任的机器生成的uuid列表时,您可以很容易地知道是否有许多uuid是由同一台机器生成的,或者推断它们之间的一些时间关系。

  • 版本4:这些是从随机(或伪随机)数字生成的。如果您只需要生成一个UUID,这可能就是您想要的。这个版本的优点是,在调试和查看与uuid匹配的一长串信息时,可以更快地发现匹配。

如果需要从给定的名称生成可重复的uuid,则需要版本3或版本5。如果您正在与其他系统交互,则已经做出了这个选择,您应该检查它们使用的版本和名称空间。

  • 版本3:它从命名空间和名称的MD5散列生成唯一ID。如果正在处理非常严格的资源要求(例如一个非常繁忙的Arduino板),使用这个。

  • Version 5:这将从命名空间和名称的SHA-1散列生成唯一ID。这是更安全且通常推荐的版本。

如果需要随机数,请使用随机数库。如果你想要一个有效0.00的唯一标识符…这里还有很多0…001%的碰撞概率,您应该使用UUIDv1。关于UUIDv3和v5,请参阅Nick的帖子。

UUIDv1不安全。这不是命中注定的。这意味着它是唯一的,而不是不可猜测的。UUIDv1使用当前时间戳,加上一个机器标识符,再加上一些随机的东西来生成一个永远不会再由该算法生成的数字。这适用于事务ID(即使每个人都在处理数百万事务/秒)。

老实说,我不明白为什么UUIDv4存在……从读取RFC4122,看起来这个版本并没有消除冲突的可能性。它只是一个随机数发生器。如果这是真的,那么世界上很有可能会有两台机器最终创建相同的“uuid”v4(加上引号是因为没有一种机制可以保证通用的uuniqueness)。在这种情况下,我认为该算法不属于描述生成唯一值的方法的RFC。它属于一个关于产生随机性的RFC。对于一组随机数:

chance_of_collision = 1 - (set_size! / (set_size - tries)!) / (set_size ^ tries)

Postgres文档描述了__abc0之间的区别。其中有几个:

V3:

uuid_generate_v3(namespace uuid, name text) -这个函数使用指定的输入名称在给定的命名空间中生成版本3的UUID。

V4:

uuid_generate_v4 -这个函数生成一个版本4的UUID,它完全由随机数派生。

因为它还没有被提到:如果你希望能够按照创建时间对实体排序,而不需要单独的显式时间戳,你可以使用uuidv1。虽然这不是100%的精确,在许多情况下也不是最好的方法(由于缺乏显式性),但在某些情况下很方便,例如当您使用Cassanda数据库时。

  • 版本1:使用时间戳和单调计数器的uuid。
  • 版本3:基于某些数据的MD5哈希的uuid。
  • 版本4:带有随机数据的uuid。
  • 版本5:基于某些数据的SHA1哈希的uuid。
  • 版本6:使用时间戳和单调计数器的uuid。
  • Version 7:使用Unix时间戳的uuid。
  • Version 8:使用用户自定义数据的uuid。

更多信息请访问生锈的文档