使用哪个UUID版本?

use*_*143 298 uuid

你应该使用哪个版本的UUID?我看到很多线程解释了每个版本的含义,但是我无法弄清楚哪些应用程序最适合.

Gab*_*abe 369

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

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

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

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

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

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

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

  • 我想补充一点:如果你需要从给定的名称生成一个"可再现的"UUID,你需要一个版本3或版本5.如果你给该算法输入相同的输入,它将生成相同的输出. (12认同)
  • 版本2发生了什么? (8认同)
  • 关于版本1"不推荐"的评论过于简单化.在许多情况下,这些确实很好并且更可取.但是,如果您有安全问题从UUID泄漏这些信息中的任何一项,这些信息可能对不信任的参与者可用:(a)创建UUID的机器的MAC地址,或(b)创建时的日期时间,然后避免版本1.如果这两个信息*不敏感,那么版本1是一个很好的方法. (6认同)
  • 在云计算环境(例如AWS或GAE)中,似乎将版本1的弱点减轻为遗忘.随着时间的推移,可能会有数千个不同的MAC地址应用于给定应用程序的UUID生成器,从而消除了可预测性和/或可跟踪性. (3认同)
  • @ user239558鉴于UUID的目标是其唯一性,UUIDv5仍然是首选. (3认同)
  • @Deimos考虑到您设想的任何可能的方案,可能的UUID的上限为2^128。因此,无论我们使用哪个版本,与 (2^128+1) 个不同输入发生冲突的概率实际上都是 1。 (3认同)
  • 如果想要0(不是无穷小但实际上是0)碰撞概率,版本1 UUID可能是完全合适的.在任何情况下,UUID都不应用于安全目的,如RFC4122所述:https://tools.ietf.org/html/rfc4122#section-6 (2认同)
  • @MatthewWoo 它没有广泛用于开源基金会(OSF)分布式计算环境(DCE)之外的任何东西。根据 RFC,版本 2 是“DCE 安全版本,带有嵌入式 POSIX UID”。出于所有实际目的以及大多数使用的系统之间的互操作性,您将使用 RFC 4122 中指定的其他 4 个版本的 UUID 之一。 (2认同)
  • @Jus12 绝对的。不知道我的意思是什么。我认为 v1 使用 MAC 地址,因此使用两个不同 MAC 地址运行的两个生成器永远不会发生冲突。然而,任何类型的 UUID 的数量都是有限的,因此任何生成器最终都会与自身发生冲突。 (2认同)

anr*_*gen 47

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

UUIDv1不安全.它并不意味着.它意味着独特,不可猜测.UUIDv1使用当前时间戳,加上一个机器标识符,再加上一些随机的东西来制作一个永远不会再被该算法生成的数字.这适用于交易ID(即使每个人都在进行数百万次交易).

说实话,我不明白为什么UUIDv4存在...从阅读RFC4122,看起来该版本不会消除碰撞的可能性.它只是一个随机数发生器.如果这是真的,那么世界上两台机器的机会很大,最终会创建相同的"UUID"v4(引用因为没有保证U.niversal U.niqueness的机制).在那种情况下,我不认为该算法属于描述生成唯一值的方法的RFC.它属于关于生成随机性的RFC.对于一组随机数:

chance_of_collision = 1 - (set_size! / (set_size - tries)!) / (set_size ^ tries)
Run Code Online (Sandbox Code Playgroud)

  • 您不会看到两个UUID版本4实现发生冲突,除非[您在一个世纪内每秒生成十亿个UUID*并且*赢得一个硬币翻转](https://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates).记住,`set_size`是2 ^ 122,这是*非常大*. (62认同)
  • V4"可能"发生碰撞,但概率非常低,对于大多数用例来说,它值得冒险.Re:"世界上的两台机器最终会创建相同的'UUID'v4',当然,这不是问题,因为世界上大多数使用UUID的机器都在不同的环境中使用它们.我的意思是,如果我为自己的内部应用程序生成与内部应用程序相同的UUID,那么这无关紧要.碰撞只有在相同的环境中发生时才有意义.(请记住,即使在应用程序中,许多UUID也不必在整个应用程序中是唯一的,只是它们所使用的上下文) (27认同)
  • 你没有真正做数学.我们(作为一个物种)每秒不产生10亿UUID.所以我们在第一次碰撞(平均)之前有*超过100年. (7认同)
  • V4算法不是串行的,这意味着v4生成的前两个UUID有可能匹配.仅仅因为有很多选项,并不意味着在产生重复之前你必须用完独特的选项.这可能随时发生. (6认同)
  • 所以听起来,如果你不需要你的Guid是安全的,使用版本1.如果你需要它安全,并且感到幸运(或者真的,不觉得不幸)使用版本4. (6认同)
  • @AbhiBeckert UUIDv1 已经处理了这种提议情况的冲突。从维基百科页面来看,“13 位或 14 位“唯一”时钟序列扩展了时间戳,以便处理每个节点有多个处理器和 UUID 生成器的情况”。因此,即使在这种情况下,UUIDv1 也能保证生成唯一的 ID(UUIDv4 则不能)。 (3认同)
  • 今天,2 ^ 122在一台笔记本电脑的背景下只是"大".当你开始考虑有多少机器可以使用该算法在25年内在完全连接的物联网环境中为每个数据包生成事务id时,它会变得非常小.结果是,如果你想要独一无二,使用一种保证它的算法,而不是在有限的环境中给你一个好机会的算法. (2认同)
  • 例如,如果我有两个实体:用户和消息。除非您希望所有类型的所有实体都是唯一可识别的(但我使用过的大多数系统不需要或不这样做),否则 Users.uuid 和 Messages.uuid 可以毫无问题地发生冲突,因为它们处于不同的上下文中。 (2认同)

Nik*_*lis 15

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

这样做更容易,更安全,因为你可能并不需要生成自己,何苦编码了一个实现?在这种情况下,无论您的O/S,编程语言或框架提供什么,答案都会变得有用.例如,在Windows中,有CoCreateGuidUuidCreate或者正在使用的众多框架中提供的各种包装器之一.在Linux中有uuid_generate.

如果您出于某种原因,绝对需要生成自己的,那么至少要有远离生成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')

请注意,此UUID将与同一URL的v5 UUID不同,后者生成如下:

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

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

  • 我猜这是因为OP没有问:我如何"编写[我]自己的UUID生成算法,而不是调用大多数现代操作系统提供的UUID生成功能?" (4认同)

Hos*_*ein 14

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

阅读Rust 文档了解更多内容。