在Java中安全地生成某个范围之间的随机数

时间:2018-06-01 16:07:22

标签: java math

如何安全生成特定范围内的随机整数值?

我知道很多人之前已经问过这个问题,例如this post,但这种方法似乎并不安全。让我解释一下:

'Math'库具有Math.random(),可在[0,1]范围内生成随机值。利用这一点,可以构造像int randomInteger = Math.floor(Math.random() * (Integer.MAX_VALUE - Integer.MIN_VALUE + 1) + Integer.MIN_VALUE)这样的算法来生成Integer.MAX_VALUE和Integer.MIN_VALUE之间的随机数。但是,Integer.MAX_VALUE - Integer.MIN_VALUE将溢出。

目标不是仅生成随机数,而是均匀生成它们,这意味着1具有与Integer.MAX_VALUE相同的概率。我知道有一些解决方法,例如将大值转换为long,但问题是如何从Long.MIN_VALUE生成一个长整数值到Long.MAX_VALUE。

我也不确定其他预先编写的算法,因为它们也会溢出并导致概率分布发生变化。所以我的问题是,是否有一个只使用整数的数学方程式(没有任何长时间的转换)和Math.random()来生成从Integer.MIN_VALUE到Integer.MAX_VALUE的随机数。或者,如果有人知道任何内部没有溢出的随机生成器?

先谢谢。

3 个答案:

答案 0 :(得分:3)

  

'Math'库有Math.random(),可以在[0,1]范围内生成随机值。

所以不要使用Math.random() - 使用它:

Random r = new Random();
int i = r.nextInt();

nextInt的文档说:

  

nextInt() - 返回下一个伪随机数,从该随机数生成器的序列中均匀分布的int值。所有2 ^ 32个可能的int值都以(近似)相等的概率生成。

看来我稍微误解了这个问题,你需要long而不是int - 幸运的是合同是一样的。

long l = r.nextLong()

这将完全采用两个整数并将它们塞在一起以制作一个长的。

答案 1 :(得分:1)

更好的方法是使用 java.security.SecureRandom这是一个加密强大的随机数生成器(RNG)。

答案 2 :(得分:0)

  

随机x =新随机(1000); //代码运行并生成值1000   int i = x.nextInt();