[英]Safely generate random numbers between some range in Java
How do I safely generate a random integer value in a specific range?如何安全地生成特定范围内的随机整数值?
I know many people have asked this before, this post for example, but the method doesn't seem to be safe.我知道以前有很多人问过这个问题,例如这篇文章,但该方法似乎并不安全。 Let me explain:
让我解释:
The 'Math' library has Math.random()
which generates a random value in the range [0, 1). 'Math' 库具有
Math.random()
,它生成范围 [0, 1) 内的随机值。 Using that, one can construct an algorithm like使用它,人们可以构建一种算法,如
int randomInteger = Math.floor(Math.random() * (Integer.MAX_VALUE - Integer.MIN_VALUE + 1) + Integer.MIN_VALUE)
to generate a random number between Integer.MAX_VALUE
and Integer.MIN_VALUE
.在
Integer.MAX_VALUE
和Integer.MIN_VALUE
之间生成一个随机数。 However, Integer.MAX_VALUE - Integer.MIN_VALUE
will overflow.但是,
Integer.MAX_VALUE - Integer.MIN_VALUE
会溢出。
The goal is not to merely generate random numbers but to generate them evenly, meaning 1 has the same probability to appear as Integer.MAX_VALUE
.目标不仅仅是生成随机数,而是均匀地生成它们,这意味着 1 与
Integer.MAX_VALUE
出现的概率相同。 I know there are work-arounds to this, such as casting large values to long but then the problem again is how to generate a long integer value from Long.MIN_VALUE
to Long.MAX_VALUE
.我知道有一些变通方法,例如将大值转换为 long 但问题又是如何生成从
Long.MIN_VALUE
到Long.MAX_VALUE
的长整数值。
I'm also not sure about other pre-written algorithms as they can overflow too and cause the probability distribution to change.我也不确定其他预先编写的算法,因为它们也会溢出并导致概率分布发生变化。 So my question is whether there is a mathematical equation that uses only integers (no casting to long anywhere) and
Math.random()
to generate random numbers from Integer.MIN_VALUE
to Integer.MAX_VALUE
.所以我的问题是是否有一个数学方程只使用整数(没有在任何地方转换为 long)和
Math.random()
来生成从Integer.MIN_VALUE
到Integer.MAX_VALUE
随机数。 Or if anyone know any random generators that don't get overflow internally?或者,如果有人知道任何不会在内部溢出的随机生成器?
The 'Math' library have Math.random() which generates a random value in [0, 1) range.
'Math' 库有 Math.random(),它在 [0, 1) 范围内生成一个随机值。
So don't use Math.random()
- use this:所以不要使用
Math.random()
- 使用这个:
Random r = new Random();
int i = r.nextInt();
The docs for nextInt
say: nextInt
的文档说:
nextInt() - Returns the next pseudorandom, uniformly distributed int value from this random number generator's sequence.
nextInt() - 从这个随机数生成器的序列中返回下一个伪随机、均匀分布的 int 值。 All 2^32 possible int values are produced with (approximately) equal probability.
所有 2^32 个可能的 int 值都以(大约)相等的概率产生。
It appears I misread the question slightly, and you need long
not int
- luckily the contract is the same.看来我稍微误解了这个问题,你需要
long
而不是int
- 幸运的是合同是一样的。
long l = r.nextLong()
This will quite literally take two ints and jam them together to make a long.从字面上看,这将需要两个整数并将它们塞在一起以形成一个长整数。
更好的方法可能是使用java.security.SecureRandom ,它是一种加密强随机数生成器 (RNG)。
Random x = new Random(1000);
随机 x = 新随机 (1000); // code running and generate values 1000 int i = x.nextInt();
// 代码运行并生成值 1000 int i = x.nextInt();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.