简体   繁体   English

使用哪个 UUID 版本?

[英]Which UUID version to use?

Which version of the UUID should you use?您应该使用哪个版本的 UUID? I saw a lot of threads explaining what each version entails, but I am having trouble figuring out what's best for what applications.我看到很多线程解释每个版本需要什么,但我很难弄清楚什么最适合什么应用程序。

There are two different ways of generating a UUID.生成 UUID 有两种不同的方法。

If you just need a unique ID, you want a version 1 or version 4.如果您只需要唯一 ID,则需要版本 1 或版本 4。

  • Version 1: This generates a unique ID based on a network card MAC address and a timer.版本 1:这会根据网卡 MAC 地址和计时器生成唯一 ID。 These IDs are easy to predict (given one, I might be able to guess another one) and can be traced back to your network card.这些 ID 很容易预测(给定一个,我可能会猜到另一个)并且可以追溯到您的网卡。 It's not recommended to create these.不建议创建这些。

  • Version 4: These are generated from random (or pseudo-random) numbers.版本 4:这些是从随机(或伪随机)数字生成的。 If you just need to generate a UUID, this is probably what you want.如果您只需要生成一个 UUID,这可能就是您想要的。

If you need to always generate the same UUID from a given name, you want a version 3 or version 5.如果需要始终从给定名称生成相同的 UUID,则需要版本 3 或版本 5。

  • Version 3: This generates a unique ID from an MD5 hash of a namespace and name.版本 3:这从命名空间和名称的 MD5 哈希生成唯一 ID。 If you need backwards compatibility (with another system that generates UUIDs from names), use this.如果您需要向后兼容(与另一个从名称生成 UUID 的系统),请使用它。

  • Version 5: This generates a unique ID from an SHA-1 hash of a namespace and name.版本 5:这将从命名空间和名称的 SHA-1 哈希生成唯一 ID。 This is the preferred version.这是首选版本。

If you want a random number, use a random number library.如果您想要随机数,请使用随机数库。 If you want a unique identifier with effectively 0.00...many more 0s here...001% chance of collision, you should use UUIDv1.如果你想要一个有效的唯一标识符 0.00...这里还有更多的 0...001% 的碰撞机会,你应该使用 UUIDv1。 See Nick's post for UUIDv3 and v5.有关 UUIDv3 和 v5,请参阅 Nick 的帖子。

UUIDv1 is NOT secure. UUIDv1 不安全。 It isn't meant to be.它不应该是。 It is meant to be UNIQUE, not un-guessable.它应该是唯一的,而不是不可猜测的。 UUIDv1 uses the current timestamp, plus a machine identifier, plus some random-ish stuff to make a number that will never be generated by that algorithm again. UUIDv1 使用当前时间戳,加上一个机器标识符,再加上一些随机的东西来制作一个永远不会被该算法再次生成的数字。 This is appropriate for a transaction ID (even if everyone is doing millions of transactions/s).这适用于事务 ID(即使每个人都在进行数百万次事务/秒)。

To be honest, I don't understand why UUIDv4 exists... from reading RFC4122 , it looks like that version does NOT eliminate possibility of collisions.老实说,我不明白为什么 UUIDv4 存在......从阅读RFC4122 来看,该版本似乎并没有消除冲突的可能性。 It is just a random number generator.它只是一个随机数生成器。 If that is true, than you have a very GOOD chance of two machines in the world eventually creating the same "UUID"v4 (quotes because there isn't a mechanism for guaranteeing U.niversal U.niqueness).如果这是真的,那么您很有可能在世界上有两台机器最终创建相同的“UUID”v4(引用是因为没有保证通用唯一性的机制)。 In that situation, I don't think that algorithm belongs in a RFC describing methods for generating unique values.在那种情况下,我认为该算法不属于描述用于生成唯一值的方法的 RFC。 It would belong in a RFC about generating randomness.它属于关于生成随机性的 RFC。 For a set of random numbers:对于一组随机数:

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

That's a very general question.这是一个很笼统的问题。 One answer is: "it depends what kind of UUID you wish to generate".一个答案是:“这取决于您希望生成什么样的 UUID”。 But a better one is this: "Well, before I answer, can you tell us why you need to code up your own UUID generation algorithm instead of calling the UUID generation functionality that most modern operating systems provide?"但更好的是:“好吧,在我回答之前,您能告诉我们为什么需要编写自己的 UUID 生成算法,而不是调用大多数现代操作系统提供的 UUID 生成功能吗?”

Doing that is easier and safer, and since you probably don't need to generate your own, why bother coding up an implementation?这样做更容易、更安全,而且由于您可能不需要生成自己的,为什么还要编写一个实现呢? In that case, the answer becomes use whatever your O/S, programming language or framework provides.在这种情况下,答案就是使用您的操作系统、编程语言或框架提供的任何内容。 For example, in Windows, there is CoCreateGuid or UuidCreate or one of the various wrappers available from the numerous frameworks in use.例如,在 Windows 中,有CoCreateGuidUuidCreate或可从使用的众多框架中获得的各种包装器之一。 In Linux there is uuid_generate .在 Linux 中有uuid_generate

If you, for some reason, absolutely need to generate your own, then at least have the good sense to stay away from generating v1 and v2 UUIDs.如果您出于某种原因绝对需要生成自己的 UUID,那么至少要远离生成 v1 和 v2 UUID。 It's tricky to get those right.把这些做对是很棘手的。 Stick, instead, to v3, v4 or v5 UUIDs.相反,坚持使用 v3、v4 或 v5 UUID。

Update : In a comment, you mention that you are using Python and link to this .更新:在评论中,您提到您正在使用 Python 并链接到此. Looking through the interface provided, the easiest option for you would be to generate a v4 UUID (that is, one created from random data) by calling uuid.uuid4() .查看提供的界面,最简单的选择是通过调用uuid.uuid4()生成 v4 UUID(即,从随机数据创建的uuid.uuid4()

If you have some data that you need to (or can) hash to generate a UUID from, then you can use either v3 (which relies on MD5) or v5 (which relies on SHA1).如果您有一些数据需要(或可以)散列以从中生成 UUID,那么您可以使用 v3(依赖于 MD5)或 v5(依赖于 SHA1)。 Generating a v3 or v5 UUID is simple: first pick the UUID type you want to generate (you should probably choose v5) and then pick the appropriate namespace and call the function with the data you want to use to generate the UUID from.生成 v3 或 v5 UUID 很简单:首先选择您想要生成的 UUID 类型(您可能应该选择 v5),然后选择适当的命名空间并使用您想要用来生成 UUID 的数据调用该函数。 For example, if you are hashing a URL you would use NAMESPACE_URL :例如,如果您对 URL 进行哈希处理,您将使用NAMESPACE_URL

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

Please note that this UUID will be different than the v5 UUID for the same URL, which is generated like this:请注意,此 UUID 将与同一 URL 的 v5 UUID 不同,其生成方式如下:

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

A nice property of v3 and v5 URLs is that they should be interoperable between implementations. v3 和 v5 URL 的一个很好的特性是它们应该在实现之间可以互操作。 In other words, if two different systems are using an implementation that complies with RFC4122, they will (or at least should ) both generate the same UUID if all other things are equal (ie generating the same version UUID, with the same namespace and the same data).换言之,如果两个不同的系统使用的是实施与RFC4122符合规定,它们将(或至少)两者产生相同的UUID,如果所有其他方面是相等的(即,产生相同的版本UUID,具有相同的命名空间和相同的数据)。 This property can be very helpful in some situations (especially in content-addressible storage scenarios), but perhaps not in your particular case.某些情况下(尤其是在内容可寻址的存储方案中),此属性可能非常有用,但可能不适用于您的特定情况。

Postgres documentation describes the differences between UUID s. Postgres 文档描述了UUID之间的差异。 A couple of them:其中有几个:

V3: V3:

uuid_generate_v3(namespace uuid, name text) - This function generates a version 3 UUID in the given namespace using the specified input name. uuid_generate_v3(namespace uuid, name text) - 此函数使用指定的输入名称在给定的命名空间中生成版本 3 UUID。

V4: V4:

uuid_generate_v4 - This function generates a version 4 UUID, which is derived entirely from random numbers. uuid_generate_v4 - 此函数生成版本 4 UUID,该 UUID 完全来自随机数。

Since it's not mentioned yet: you can use uuidv1 if you want to be able to sort your entities by creation time without a separate, explicit timestamp.由于尚未提及:如果您希望能够按创建时间对实体进行排序而无需单独的显式时间戳,则可以使用uuidv1 While that's not 100 % precise and in many cases not the best way to go (due to the lack of explicity), it comes handy in some scenarios, eg when you're working with a Cassanda database.虽然这不是 100% 精确,并且在许多情况下不是最好的方法(由于缺乏明确性),但它在某些情况下很方便,例如当您使用 Cassanda 数据库时。

  • Version 1: UUIDs using a timestamp and monotonic counter.版本 1:使用时间戳和单调计数器的 UUID。
  • Version 3: UUIDs based on the MD5 hash of some data.版本 3: UUID 基于部分数据的 MD5 hash。
  • Version 4: UUIDs with random data.版本 4:具有随机数据的 UUID。
  • Version 5: UUIDs based on the SHA1 hash of some data.版本 5: UUID 基于部分数据的 SHA1 hash。
  • Version 6: UUIDs using a timestamp and monotonic counter.版本 6:使用时间戳和单调计数器的 UUID。
  • Version 7: UUIDs using a Unix timestamp.版本 7:使用 Unix 时间戳的 UUID。
  • Version 8: UUIDs using user-defined data.版本 8:使用用户定义数据的 UUID。

Read more at Rust documentation .Rust 文档中阅读更多内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM