题
如果我使用Long uuid = UUID.randomUUID().getMostSignificantBits()
怎么可能是它得到一个碰撞。它切断了至少显著位,所以你遇到碰撞的可能性,对吧?
解决方案
根据的文档,所述静态方法UUID.randomUUID()
生成4型UUID。
这意味着6位被用于某种类型的信息和剩余的122位被随机分配。
在六个非随机比特被分布有四个在UUID的最显著一半,两个在至少显著一半。所以,你的UUID的最显著一半包含随机性的60位,这意味着你平均需要生成2 ^ 30的UUID得到一个碰撞(与2 ^ 61为全UUID)。
所以,我要说你是相当安全的。但是请注意,这是用于其它类型的UUID的绝对不正确的,因为卡尔Seleborg提到。
顺便说一下,你会通过使用至少显著一半的UUID的(或仅产生随机长使用的SecureRandom)稍好一些。
其他提示
雷蒙德陈有一个非常优秀的博客文章上这样的:
我认为,这是用于使用randomUUID最好的例子:
您是最好只产生一个随机长值,则所有的比特是随机的。在Java 6中,新的随机()使用System.nanoTime()加一个计数器作为种子。
有不同水平的独特性。
如果您需要跨多台机器的独特性,你可以有一个中央数据库表分配唯一的ID,甚至是唯一的ID的批次。
如果您只是需要有独特性在一个应用程序,你可以只是有一个计数器(或从的currentTimeMillis()* 1000或nanoTime()根据您的要求启动计数器)
使用时间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();
}