Java中使用SecureRandom生成唯一的正长整型

SecureRandom类位于java.security包中,专为加密目的和关键安全情况而设计,使用确保高度不可预测性的算法。

在本教程中,我们将讨论使用SecureRandom生成唯一的正长整型值,并探讨生成多个值时避免冲突的安全性。

使用nextLong()
SecureRandom的nextLong ()方法返回一个long类型的值,它是一个随机的 64 位数字。这些值随机分布在极宽的值范围内,从Long.MIN_VALUE (-2^63) 到Long.MAX_VALUE (2^63 – 1)。

该方法继承自Random类。然而,由于使用更多数量的种子位,因此在冲突概率方面保证更安全。

在底层,它使用伪随机数生成器 (PRNG)(也称为确定性随机位生成器或 DRBG)与操作系统提供的熵源相结合。

让我们看看如何使用它来生成随机长值:

new SecureRandom().nextLong();

如果我们打印此方法调用的一些结果,我们可能会看到如下输出:

4926557902899092186
-2282075914544479463
-4653180235857827604
6589027106659854836

因此,如果我们只需要正值,那么我们还需要使用Math.abs():

SecureRandom secureRandom = new SecureRandom();
long randomPositiveLong = Math.abs(secureRandom.nextLong());


这样,就可以保证结果始终为正:

assertThat(randomPositiveLong).isNotNegative();

碰撞概率
因为我们需要生成唯一的值,所以确保碰撞的概率足够低非常重要。

正如我们上面提到的,nextLong()方法生成一个范围从 -2^63 到 2^63 – 1 的64 位随机长值。随后,通过应用Math.abs(),我们消除任何负号,从而产生范围从 0 到 2^62 – 1。

因此,碰撞概率计算为 1 / 2^62。以十进制形式表示,此概率约为 0.000000000000000000216840434497100900。对于大多数实际应用,我们可以认为这个低概率是微不足道的。

假设它每秒生成一个值,平均而言,在大约 (2^62) / (60) / (60) / (24) / (365.25) 年(即大约 146,135,511,523 年)的时间内只会发生一次碰撞。延长的时间进一步凸显了碰撞事件的罕见性。

结论
在本文中,我们讨论了如何使用SecureRandom生成唯一的正长值。这种方法被认为是有效的,因为它确保了高度的不可预测性,并且碰撞的概率对于大多数应用来说是微不足道的,因此它适合在各种情况下使用。