randomUUID 是否给出唯一的 ID?

2022-09-01 04:50:32

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

UUID token = UUID.randomUUID();
user.setSessionId(token.toString());
Sessions.INSTANCE.sessions.put(user.getName(), user.getSessionId());

但是,我不确定如何防止重复会话令牌。

例如:当 user1 登录并获取令牌,而 user2 登录并同时获取令牌时,是否存在这种情况。87955dc9-d2ca-4f79-b7c8-b0223a32532a87955dc9-d2ca-4f79-b7c8-b0223a32532a

有没有更好的方法来做到这一点?


答案 1

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

来自维基百科:

随机生成的 UUID 有 122 个随机位。在总共 128 位中,有四位用于版本(“随机生成的 UUID”),两位用于变体(“Leach-Salz”)。

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

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

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

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

为了正确看待这些数字,估计某人被陨石击中的年度风险是170亿分之一的机会,这意味着概率约为0.00000000006(6×10-11),相当于一年内产生数百万亿>UUID并有一个重复的几率。换句话说,只有在接下来的100年里每秒产生10亿个UUID之后,只产生一个重复的概率就约为50%。如果地球上的每个人都拥有6亿个UUID,那么重复的概率约为50%。


答案 2

由于 UUID 的大小有限,因此它不可能在所有空间和时间中都是唯一的。

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