randomUUID是否提供唯一ID?

时间:2014-01-08 15:28:29

标签: java random uuid

我正在尝试为我的REST API创建会话令牌。每次用户登录时,我都会通过

创建一个新令牌
UUID token = UUID.randomUUID();
user.setSessionId(token.toString());
Sessions.INSTANCE.sessions.put(user.getName(), user.getSessionId());

但是,我不确定如何防止重复的sessionTokens。

例如:当user1登录并获得令牌87955dc9-d2ca-4f79-b7c8-b0223a32532a并且用户2登录并且获得令牌87955dc9-d2ca-4f79-b7c8-b0223a32532a时,是否会出现这种情况。

有更好的方法吗?

4 个答案:

答案 0 :(得分:39)

如果您遇到UUID冲突,请继续玩彩票。

来自维基百科:

  

随机生成的UUID有122个随机位。总共128个   比特,四个比特用于版本('随机生成的UUID'),   变量的两位('Leach-Salz')。

     

随机UUID,   可以使用计算两个具有相同值的机会   概率论(生日悖论)。使用近似值

     

p(n)\approx 1-e^{-\tfrac{n^2}{{2x}}}

     

这些是概率   计算n个UUID后出现意外冲突,x = 2122:

     概率   68,719,476,736 = 236 0.0000000000000004(4×10-16)   2,199,023,255,552 = 241 0.0000000000004(4×10-13)   70,368,744,177,664 = 246 0.0000000004(4×10-10)

     

将这些数字放入视角,   估计有人被陨石击中的年度风险   170亿的一次机会,这意味着概率大约是   0.00000000006(6×10-11),相当于创造几十万亿的几率> UUID在一年内有一个重复。在   换句话说,只有在每秒产生10亿UUID之后   在接下来的100年里,创造一个重复的概率   将是约50%。一次重复的概率大约是   如果地球上的每个人拥有6亿UUID,则为50%。

答案 1 :(得分:4)

Oracle UUID文档。 http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html

他们使用来自互联网工程任务组的算法。 http://www.ietf.org/rfc/rfc4122.txt

摘要引用。

  

UUID长度为128位,可以保证唯一性   空间和时间。

虽然摘要声明了保证,但只有3.4 x 10^38组合。 CodeChimp

答案 2 :(得分:2)

由于UUID的大小有限,因此无法在所有空间和时间内保持唯一。

如果您需要在任何合理用例中保证唯一的UUID,您可以使用Log4j 2的Uuid.getTimeBasedUuid()。只要您每毫秒产生的UUID少于10,000 UUID,它就保证在8,900年内是独一无二的。

答案 3 :(得分:0)

来自 UUID.randomUUID() Javadoc:

<块引用>

用于检索类型 4(伪随机生成)UUID 的静态工厂。 UUID 是使用加密强的伪随机数生成器生成的。

这是随机的,因此肯定会发生碰撞,正如上面/下面的评论中确认的那样,很早就检测到了碰撞。 我建议您使用版本 1(基于时间)而不是版本 4(基于随机)。

可能的解决方案:

1) 来自 Log4j 的 UUID 实用程序

您可以使用 Log4j UuidUtil.getTimeBasedUuid() 中的第 3 方实现,该实现基于当前时间戳(从 1582 年 10 月 10 日起以 100 纳秒为单位测量),并与创建 UUID 的设备的 MAC 地址连接。请参阅工件 log4j-core 中的软件包 org.apache.logging.log4j.core.util

2) 来自 FasterXML 的 UUID 实用程序

还有来自 FasterXML Generators.timeBasedGenerator().generate() 的第 3 方实现,它也基于时间和 MAC 地址。请参阅工件 java-uuid-generator 中的软件包 com.fasterxml.uuid

3) 自己做

或者您可以使用核心 Java 的构造函数 new UUID(long mostSigBits, long leastSigBits) 实现您自己的。请参阅以下非常好的解释 Baeldung - Guide to UUID in Java,其中 1582 年 10 月 15 日(实际上是非常著名的一天)用于实施。