使用Java中的UUID的最显著位碰撞的可能性

问题描述 投票:231回答:5

如果我使用Long uuid = UUID.randomUUID().getMostSignificantBits()怎么可能是它得到一个碰撞。它切断了至少显著位,所以你遇到碰撞的可能性,对不对?

java collision uuid
5个回答
211
投票

根据the documentation,静态方法UUID.randomUUID()生成4型UUID。

这意味着6位被用于某种类型的信息和剩余的122位被随机分配。

六个非随机位分布有四个在UUID的最显著半和两个在最显著的一半。所以,你的UUID的最显著一半包含随机性的60位,这意味着你平均需要生成2 ^ 30的UUID得到一个碰撞(与2 ^ 61为全UUID)。

所以,我要说你是相当安全的。但请注意,这是绝对不能用于其他类型的UUID的真实,卡尔Seleborg提到。

顺便说一句,你会通过使用UUID的至少一半显著(或只是产生一个随机长使用的SecureRandom)稍好一些。


55
投票

雷蒙德陈有这个真正优秀的博客文章:

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


13
投票

我认为这是使用randomUUID最好的例子:

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


10
投票

您是关只是产生一个随机长值较好,那么所有的位是随机的。在Java 6,新的随机()使用System.nanoTime()加上一个计数器作为种子。

有不同程度的独特性。

如果你需要跨越许多机器的独特性,你可以有一个中央数据库表分配唯一的ID,甚至是唯一的ID的批次。

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


7
投票

使用时间YYYYDDDD(逐年+日)为前缀。这降低表和索引数据库碎片。此方法返回byte[40]。我用它在混合环境中,其中的Active Directory SID(varbinary(85))是LDAP用户密钥,并且用于非LDAP用户的应用自动生成的ID。另外,大量的事务表,每天的交易(银行业)不能使用标准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();
}
© www.soinside.com 2019 - 2024. All rights reserved.