Java 中使用 UUID 最高有效位发生冲突的可能性

发布于 2024-07-08 21:52:33 字数 106 浏览 11 评论 0原文

如果我使用 Long uuid = UUID.randomUUID().getMostSignificantBits() 发生碰撞的可能性有多大。 它会切断最低有效位,因此有可能会遇到冲突,对吧?

If I'm using Long uuid = UUID.randomUUID().getMostSignificantBits() how likely is it to get a collision. It cuts off the least significant bits, so there is a possibility that you run into a collision, right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我一向站在原地 2024-07-15 21:52:33

根据 文档,静态方法 < code>UUID.randomUUID() 生成类型 4 UUID。

这意味着 6 位用于某些类型信息,其余 122 位是随机分配的。

六个非随机位分布在 UUID 的最高有效一半中,两个在最低有效一半中。 因此,UUID 的最重要的一半包含 60 位随机性,这意味着您平均需要生成 2^30 个 UUID 才能发生冲突(相比之下,完整 UUID 需要生成 2^61 个)。

所以我想说你还是比较安全的。 但请注意,正如 Carl Seleborg 提到的那样,对于其他类型的 UUID 来说绝对不是这样。

顺便说一句,使用 UUID 的最低有效一半(或者只是使用 SecureRandom 生成随机长整数)会稍微好一些。

According to the documentation, the static method UUID.randomUUID() generates a type 4 UUID.

This means that six bits are used for some type information and the remaining 122 bits are assigned randomly.

The six non-random bits are distributed with four in the most significant half of the UUID and two in the least significant half. So the most significant half of your UUID contains 60 bits of randomness, which means you on average need to generate 2^30 UUIDs to get a collision (compared to 2^61 for the full UUID).

So I would say that you are rather safe. Note, however that this is absolutely not true for other types of UUIDs, as Carl Seleborg mentions.

Incidentally, you would be slightly better off by using the least significant half of the UUID (or just generating a random long using SecureRandom).

栖竹 2024-07-15 21:52:33

Raymond Chen 在这方面有一篇非常出色的博客文章:

GUID 是全球唯一的,但是GUID 的子字符串不是

Raymond Chen has a really excellent blog post on this:

GUIDs are globally unique, but substrings of GUIDs aren't

遗失的美好 2024-07-15 21:52:33

我认为这是使用 randomUUID 的最佳示例:

http://www.javapractices。 com/topic/TopicAction.do?Id=56

I thinks this is the best example for using randomUUID :

http://www.javapractices.com/topic/TopicAction.do?Id=56

孤独患者 2024-07-15 21:52:33

您最好只生成一个随机长值,然后所有位都是随机的。 在 Java 6 中,new Random() 使用 System.nanoTime() 加上一个计数器作为种子。

有不同程度的独特性。

如果您需要在多台机器上保持唯一性,您可以使用一个中央数据库表来分配唯一 ID,甚至批量分配唯一 ID。

如果您只需要在一个应用程序中具有唯一性,您可以只拥有一个计数器(或根据您的要求从 currentTimeMillis()*1000 或 nanoTime() 开始的计数器)

You are better off just generating a random long value, then all the bits are random. In Java 6, new Random() uses the System.nanoTime() plus a counter as a seed.

There are different levels of uniqueness.

If you need uniqueness across many machines, you could have a central database table for allocating unique ids, or even batches of unique ids.

If you just need to have uniqueness in one app you can just have a counter (or a counter which starts from the currentTimeMillis()*1000 or nanoTime() depending on your requirements)

慕巷 2024-07-15 21:52:33

使用时间 YYYYDDDD(年 + 一年中的某天)作为前缀。 这减少了表和索引中的数据库碎片。 此方法返回byte[40]。 我在混合环境中使用了它,其中 Active Directory SID (varbinary(85)) 是 LDAP 用户的密钥,应用程序自动生成的 ID 用于非 LDAP 用户。 此外,交易表(银行业)中每天的大量交易不能使用标准 Int 类型作为键

private static final DecimalFormat timeFormat4 = new DecimalFormat("0000;0000");

public static byte[] getSidWithCalendar() {
    Calendar cal = Calendar.getInstance();
    String val = String.valueOf(cal.get(Calendar.YEAR));
    val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR));
    val += UUID.randomUUID().toString().replaceAll("-", "");
    return val.getBytes();
}

Use Time YYYYDDDD (Year + Day of Year) as prefix. This decreases database fragmentation in tables and indexes. This method returns byte[40]. I used it in a hybrid environment where the Active Directory SID (varbinary(85)) is the key for LDAP users and an application auto-generated ID is used for non-LDAP Users. Also the large number of transactions per day in transactional tables (Banking Industry) cannot use standard Int types for Keys

private static final DecimalFormat timeFormat4 = new DecimalFormat("0000;0000");

public static byte[] getSidWithCalendar() {
    Calendar cal = Calendar.getInstance();
    String val = String.valueOf(cal.get(Calendar.YEAR));
    val += timeFormat4.format(cal.get(Calendar.DAY_OF_YEAR));
    val += UUID.randomUUID().toString().replaceAll("-", "");
    return val.getBytes();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文