www*_*www 5 java random random-seed
在随机#nextLong()文档指出此方法不会返回所有可能的long值:
从此随机数生成器的序列返回下一个伪随机、均匀分布的 long 值。的一般约定nextLong是伪随机生成并返回一个 long 值。该方法nextLong由 Random 类实现,就像通过:
public long nextLong() {
return ((long) next(32) << 32) + next(32);
}
Run Code Online (Sandbox Code Playgroud)
因为 Random 类使用只有 48 位的种子,所以该算法不会返回所有可能的长值。
例如,数字8090327796378429294是可生成的,但数字8090327796378429295不是,即使它们唯一的区别是一个最低有效位,并且值本身是 63 位长。
有一种方法可以通过nextLong()使用以下算法来知道是否可以返回值:
public class JavaRandom {
private static final long ADD = 0xBL;
private static final long MULT = 0x5DEECE66DL;
private static final long TWO16 = 1L << 16;
private static final long MASK_31 = (1L << 31) - 1;
private static final long MASK_32 = (1L << 32) - 1;
private static final long MASK_48 = (1L << 48) - 1;
public static boolean canBeGeneratedByJavaRandom(long randomValue) {
long i1 = (randomValue >> 32) & MASK_32;
long i2 = (randomValue & MASK_32);
if (i2 > MASK_31) {
i1 = i1 + 1;
}
long front = i1 << 16;
for (long i = 0; i < TWO16; i++) {
long seed = front | i;
long i22 = (((seed * MULT) + ADD) & MASK_48) >> 16;
if (i22 == i2) {
return true;
}
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
如何在nextLong()不对每个可能的 64 位数字运行此检查的情况下获取可以生成的所有值?nextLong()在收集所有值之前调用并不合理,而且可能会发生冲突。