如果我正在使用Long uuid = UUID.randomUUID().getMostSignificantBits()
它有可能发生碰撞.它切断了最不重要的位,所以你有可能遇到碰撞,对吗?
根据文档,静态方法UUID.randomUUID()
生成类型4 UUID.
这意味着六位用于某些类型信息,其余122位随机分配.
六个非随机位分布在UUID的最重要的一半中有四个,在最不重要的一半中有两个.因此,UUID中最重要的一半包含60位随机性,这意味着您平均需要生成2 ^ 30个UUID才能获得冲突(相比之下,完整UUID为2 ^ 61).
所以我会说你很安全.但请注意,对于其他类型的UUID,这绝对不是正确的,正如Carl Seleborg所提到的那样.
顺便提一下,使用UUID的最不重要的一半(或者只使用SecureRandom生成随机长度)会稍微好一些.
Raymond Chen有一篇非常出色的博客文章:
GUID是全局唯一的,但GUID的子字符串不是
我认为这是使用randomUUID的最佳示例:
http://www.javapractices.com/topic/TopicAction.do?Id=56
你最好只生成一个随机的长值,然后所有的位都是随机的.在Java 6中,新的Random()使用System.nanoTime()加上一个计数器作为种子.
有不同程度的独特性.
如果您需要跨多台计算机的唯一性,则可以使用中央数据库表来分配唯一ID,甚至是批量唯一ID.
如果你只需要在一个应用程序中拥有唯一性,你可以只有一个计数器(或一个从currentTimeMillis()*1000或nanoTime()开始的计数器,具体取决于你的要求)
使用时间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(); }