Java Random 类,使用相同的种子和 nextBytes() 生成重复的数字?
假设我通过使用 new Random() 实例化静态最终 Random 对象来使用相同的种子,是否可以通过在同一实例中调用 nextBytes 两次获得相同的数字?
我知道对于任何给定的种子,可以确定所有可能的“随机”数字,并且它实际上更像是一个序列:
synchronized protected int next(int bits) {
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));
}
所以基本上如果我有以下代码:
private static final Random random = new Random();
public void doSomething() {
for (int i=0; i < 1000000000; i++) {
byte byteArray[] = new byte[8];
random.nextBytes(byteArray)
}
}
nextBytes 将在其之前生成相同字节的可能性有多大遍历它可以生成的所有可能的数字?
在返回给定位的所有可能组合之前,这会返回相同的值吗?我猜是的,但是这种情况多久会发生一次?
Assuming that I am using the same seed by instantiating a static final Random object with new Random(), is it possible to get the same number twice by calling nextBytes in the same instance?
I am aware that for any given seed, all the possible "random" numbers can be determined, and it is really more like a sequence:
synchronized protected int next(int bits) {
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));
}
So basically if I have this code:
private static final Random random = new Random();
public void doSomething() {
for (int i=0; i < 1000000000; i++) {
byte byteArray[] = new byte[8];
random.nextBytes(byteArray)
}
}
How likely is it that nextBytes will generate the same bytes before it goes thru all the possible numbers that it can generate?.
Would this return the same value before returning all the possible combinations for the given bits?. I am guessing yes, but how often would this happen?.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Random
类使用具有非常大周期的线性同余生成器。它不会长时间重复一个 int 值。使用 8 字节数组调用nextBytes
会生成两个 int 值,并将每个值分成四个 8 位值来填充数组。我相信连续调用
nextBytes
不可能生成相同的值。这意味着随机数生成器的周期为 2。 docs 指定了next
的特定行为,这使得这成为不可能。 (当然,Random
的子类可以具有您喜欢的任何类型的病态行为,但java.util.Random
的实例将表现良好。)Class
Random
uses a linear congruence generator with a very large period. It does not repeate an int value for a very long time. The call tonextBytes
with an 8-byte array generates two int values and breaks each into four 8-bit values to fill the array.I believe it is impossible for consecutive calls to
nextBytes
to generate the same values. It would mean that the random number generator would have a period of 2. The docs specify a specific behavior fornext
that makes this impossible. (A subclass ofRandom
, of course, can have any kind of pathological behavior you like, but an instance ofjava.util.Random
will be well-behaved.)nextBytes 返回与上一次迭代中返回的值相同的值的概率与 nextBytes 返回任何特定随机八个字节的概率完全相同。
好的随机数生成器不会对将返回的位做出任何保证,除了这些位是随机的这一事实之外。有时,希望生成器以随机顺序返回所有可能的值,但这通常不是随机生成器的目标。
The probability of nextBytes returning the same value that it returned in the previous iteration is exactly the same as the probability of nextBytes returning any specific random eight bytes.
A good random number generator does not make any guarantees about the bits that will be returned other than the fact that the bits will be random. Sometimes it is desirable to have a a generator return all possible values in a random order, but this is not normally the goal of a random generator.
上面的答案表明不能出现重复的相同值似乎忘记了 Java.Random 的周期长度为 2^48。因此,在遍历 RNG 周期中的所有值之前,nextInt() 完全有可能生成完全相同的整数。实际上是 2^16 次。
此外,由于整数被分成四个,即使我们必须遍历所有整数,也可能会出现相同的字节。实际上,如果是这种情况,在我们遍历所有整数值之前,每个字节值都会出现 2^24 次。然而,我知道最初的问题涉及由八个字节组成的字节数组。对于这种情况,我们将在 2^31(对于 Java 的 Random 为 2^47)调用 nextByte 后得到相同的数组(因为我们需要两个整数)。
正如我之前所说,我们不需要遍历所有整数。
也就是说,如果我们假设 nextInt() 返回的值均匀分布,那么在一系列 n 个样本中获得完全相同的整数的概率为
大约 1-((2^32 -1) / 2^32) ^(n(n-1)/2)。请参阅 http://en.wikipedia.org/wiki/Birthday_problem
我们需要的样本数量绘制有两个匹配整数的概率大于 50% 仅略高于 77000。如果我们现在假设我们统一绘制一个 2^64 数字,或两个 2^32整数(对于八个字节),那么我们在 5*10^9 个样本后得到相同的概率,约为 2^32。请注意,即使到那时我们可以看到所有整数,这仍然比 Random 的周期短得多。事实可能介于两者之间。无论如何,概率非常低,但并不像上面的帖子所建议的那样完全为零。
我错过了什么吗?
The answers above suggesting that repeated same values cannot occur seem to forget that Java.Random has a period length of 2^48. Because of that, it is entirely possible that nextInt() will generate the exact same integers BEFORE one has gone through all values in the RNG's period. 2^16 times, actually.
Also, as the integers are split in four, the same bytes could (would) appear even if we had to go through all integers. Actually, if that was the case, every byte value would appear 2^24 times before we went through all integer values. I am aware, however, that the original question concerned a byte array consisting of eight bytes. For this case, we would get the same array after 2^31 (2^47 for Java's Random) calls to nextByte (because we need two integers).
We DON'T need to go through all the integers, as i said before.
That being said, if we assume a uniform distribution of the values returned by nextInt(), then the probability of getting the exact same integers in a series of n samples is
approximately 1-((2^32 -1) / 2^32) ^(n(n-1)/2). See http://en.wikipedia.org/wiki/Birthday_problem
The number of samples we need to draw to have a probability greater than 50% to have two matching integers is only a little more than 77000. If we now assume we instead uniformly draw a 2^64 number, or two 2^32 integers (for the eight bytes), then we get the same probability after 5*10^9 samples, which is about 2^32. Note that even if by that time, we could have seen all integers, this is still considerably shorter than Random's period. The truth is probably somewhere in-between. Anyway, the probability is very low, but not entirely zero as suggested by posts above.
Am i missing something?