使用哪个UUID版本?


332

您应该使用哪个版本的UUID?我看到很多线程在解释每个版本的含义,但是我在确定最适合哪种应用程序方面遇到了麻烦。


2
您有什么选择?
加布

任何适用于python的东西。所以我猜这是docs.python.org/2/library/uuid.html。1,3,4,5。
user1802143 2013年

如果您对版本3和5感到好奇,请参阅此问题,生成v5 UUID。什么是名称和名称空间?
罗勒·布尔克

Answers:


414

生成UUID的方式有两种。

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

  • 版本1:这会根据网卡MAC地址和计时器生成唯一的ID。这些ID很容易预测(给定一个,我也许可以猜出另一个),并且可以追溯到您的网卡。不建议创建这些。

  • 版本4:这些是从随机(或伪随机)数生成的。如果仅需要生成UUID,则可能正是您想要的。

如果需要始终从给定名称生成相同的UUID,则需要版本3或版本5。

  • 版本3:这将从名称空间和名称的MD5哈希生成唯一ID。如果需要向后兼容(与另一个从名称生成UUID的系统兼容),请使用此功能。

  • 版本5:这将从名称空间和名称的SHA-1哈希生成唯一ID。这是首选版本。


17
我要补充一点:如果您需要根据reproducible给定的名称生成UUID,则需要版本3或版本5。如果向该算法提供相同的输入,它将生成相同的输出。
anregen 2014年

3
在云计算环境(例如AWS或GAE)中,似乎可以消除版本1的弱点。随着时间的流逝,可能有成千上万个不同的MAC地址应用于给定应用程序的UUID生成器,从而消除了可预测性和/或可追溯性。
布法罗拉博

3
@ user239558鉴于UUID的目标是其唯一性,所以仍可以首选UUIDv5。
Epicurist

7
关于“不推荐”版本1的评论过于简单。在许多情况下,这些的确很好并且更可取。但是,如果您担心从UUID泄漏这两项信息中的任何一项,而这些信息可能会被不信任的参与者使用:(a)创建UUID的计算机的MAC地址,或(b)创建时的日期时间,然后避免使用版本1。如果这两条信息都不敏感,那么版本1是一个很好的选择。
罗勒·布尔克

9
版本2发生了什么?
马修·吴

53

如果需要随机数,请使用随机数库。如果您想要一个唯一的标识符,有效地具有0.00 ...这里有更多0,... 001%的碰撞机会,则应该使用UUIDv1。有关UUIDv3和v5,请参见Nick的帖子。

UUIDv1不安全。并非如此。它是唯一的,不是不可猜测的。UUIDv1使用当前时间戳,再加上机器标识符,再加上一些随机的东西来生成一个数字,该数字将不再由该算法再次生成。这适用于事务处理ID(即使每个人都在进行数百万次事务处理)。

老实说,我不理解为什么UUIDv4存在...从阅读RFC4122来看,该版本似乎无法消除发生冲突的可能性。它只是一个随机数生成器。如果是这样的话,那么世界上有两台机器最终创建相同的“ UUID” v4的可能性就非常大(要报价是因为没有一种机制可以保证通用的U.niqueness)。在那种情况下,我认为该算法不属于描述生成唯一值的方法的RFC。它属于关于生成随机性的RFC中。对于一组随机数:

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

67
您将不会看到两个UUID版本4的实现发生冲突,除非您在一个世纪内每秒产生十亿个UUID 赢得一次掷硬币。请记住,set_size是2 ^ 122,这非常大
凯文

8
V4算法不是串行的,这意味着v4生成的前两个UUID可能会匹配。仅仅因为有很多选项,并不意味着在生成重复项之前,您必须先用完唯一的选项。这可能随时发生。
anregen

7
您没有真正进行数学运算。我们(作为一个物种)不会每秒产生10亿个UUID。因此,我们有更长的 100多年,直到第一次碰撞(平均)。
凯文

31
V4“可能”发生冲突,但对于大多数用例而言,其风险极低,因此值得承担。回复:“当然,“世界上有两台计算机最终创建了相同的'UUID'v4”,但这不是问题,因为世界上大多数使用UUID的计算机都在不同的上下文中使用它们。我的意思是,如果我为自己的内部应用程序生成的UUID与您为内部应用程序生成的UUID相同,那么没关系。冲突只有在相同的情况下发生才重要。(请记住,即使在一个应用程序中,许多UUID不必在整个应用程序中是唯一的,只是在使用它们的上下文中是唯一的)

6
所以,它听起来就像,如果你不需要你的Guid是安全的,使用版本1.如果你需要它的安全,而感到幸运(或真的,不觉得不吉利)使用版本4
Vaccano

16

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

这样做更容易,更安全,并且由于您可能不需要生成自己的代码,因此为什么还要编写实现代码呢?在这种情况下,无论您的O / S,编程语言或框架提供什么,答案都将变得可用。例如,在Windows中,有CoCreateGuidUuidCreate或使用中的众多框架提供的各种包装之一。在Linux中,有uuid_generate

如果出于某种原因您绝对需要生成自己的UUID ,则至少应避免生成v1和v2 UUID。正确设置是很难的。而是坚持使用v3,v4或v5 UUID。

更新:在评论中,您提到您正在使用Python并链接到此。通过提供的界面查看,最简单的选择是通过调用来生成v4 UUID(即从随机数据创建的UUID)uuid.uuid4()

如果您有一些需要(或可以)哈希以生成UUID的数据,则可以使用v3(依赖于MD5)或v5(依赖于SHA1)。生成v3或v5 UUID很简单:首先选择要生成的UUID类型(您可能应该选择v5),然后选择适当的名称空间,并使用要用于生成UUID的数据调用函数。例如,如果您要对URL进行哈希处理,则可以使用NAMESPACE_URL

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

请注意,对于同一URL,此UUID将不同于v5 UUID,其生成方式如下:

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

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


4
我想这是因为OP没有问:我如何“编码自己的UUID生成算法,而不是调用大多数现代操作系统提供的UUID生成功能?”
anregen 2014年

除此之外,我认为这是对UUIDv3和v5的很好解释。关于我为什么认为v1可以是一个不错的选择的原因,请参见下面的答案。
2014年

NAMESPACE_URL是什么?这是我可以获得的变量?来自哪里?
stackdave

@stackdave NAMESPACE_URL是一个UUID,通常等于RFC-41226ba7b811-9dad-11d1-80b4-00c04fd430c8第30页上的建议。
杰米·里丁

2

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

V3:

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

V4:

uuid_generate_v4 -此函数生成版本4 UUID,该版本完全由随机数得出。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.