使用哪个UUID版本?

你应该使用哪个版本的UUID? 我看到了很多解释每个版本需要什么的线程,但是我很难找出哪些应用程序最适合。

有两种不同的方式来生成UUID。

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

  • 版本1:这将基于网卡MAC地址和计时器生成唯一的ID。 这些ID很容易预测(给出一个,我可能会猜到另一个),可以追溯到你的网卡。 不build议创build这些。

  • 版本4:这些是从随机(或伪随机)数字生成的。 如果你只需要生成一个UUID,这可能是你想要的。

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

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

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

如果你想要一个随机数,使用一个随机数字库。 如果你想要一个有效的0.00 …更多的0这里的唯一标识符… 001%的机会碰撞,你应该使用UUIDv1。 请参阅Nick的post,了解UUIDv3和v5。

UUIDv1不安全。 这并不意味着。 它是唯一的,不是不可猜测的。 UUIDv1使用当前的时间戳,外加一个机器标识符,加上一些随机的东西来创build一个永远不会被该algorithm生成的数字。 这适用于交易ID(即使每个人都在执行数百万次交易)。

说实话,我不明白为什么UUIDv4存在…从阅读RFC4122 ,它看起来像版本不能消除碰撞的可能性。 这只是一个随机数发生器。 如果这是真的,那么世界上最好有两台机器的机会最终会创造出相同的“UUID”v4(引号是因为没有保证通用机器的机制)。 在这种情况下,我不认为这个algorithm属于一个描述生成唯一值的方法的RFC。 它属于一个关于产生随机性的RFC。 对于一组随机数字:

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

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

这样做更简单,更安全,而且由于您可能不需要自己创build,为什么还要编写一个实现呢? 在这种情况下,无论您的O / S,编程语言或框架如何,答案都可以使用。 例如,在Windows中,有CoCreateGuid或UuidCreate,或者是在众多使用的框架中提供的各种包装器之一。 在Linux中有uuid_generate 。

如果你出于某种原因绝对需要自己创build,那么至less应该避免生成v1和v2的UUID。 让他们正确的是非常棘手的。 而是坚持到v3,v4或v5 UUID。

更新 :在评论中,你提到你正在使用Python并链接到这个 。 通过提供的界面来看, 最简单的select是通过调用uuid.uuid4()来生成一个v4 UUID(也就是从随机数据创build的uuid.uuid4()

如果您有一些需要(或可以)散列来生成UUID的数据,则可以使用v3(依赖于MD5)或v5(依赖于SHA1)。 生成v3或v5 UUID很简单:首先select要生成的UUIDtypes(您应该selectv5),然后select合适的名称空间并使用要用于生成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的实现,它们将(或者至less应该 )都生成相同的UUID,如果所有其他事物相同(即生成相同的版本UUID,具有相同的命名空间和相同的数据)。 在某些情况下(尤其是在内容可寻址的存储场景中),此属性可能非常有用,但可能并不适用于您的特定情况。