Get seed of Java's RNG with getInt(int n) method
我对Java RNG是如何工作的很感兴趣。我已经了解到使用
因为
我测试了一个残差测试,测试了所有与初始值一致的可设置位置的数字对,但这对于计算机来说是非常长和困难的。
关于如何有效地获得种子还有其他想法吗?
您应该能够使用反射:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Random r = new Random(1); Field f; try { f = r.getClass().getDeclaredField("seed"); f.setAccessible(true); AtomicLong seed = (AtomicLong) f.get(r); System.out.println("seed:" + seed); f = r.getClass().getDeclaredField("mask"); f.setAccessible(true); Long mask = (Long) f.get(r); System.out.println("mask:" + mask); f = r.getClass().getDeclaredField("multiplier"); f.setAccessible(true); Long multiplier = (Long) f.get(r); System.out.println("multiplier:" + multiplier); long initialSeed = (seed.longValue() ^ multiplier); System.out.println("restored initial seed:" + initialSeed); } catch (NoSuchFieldException e1) { } catch (SecurityException e2) { } catch (IllegalAccessException e3) { } catch (IllegalArgumentException e4) { } |
我的机器上的输出:
1 2 3 4 | seed: 25214903916 mask: 281474976710655 multiplier: 25214903917 restored initial seed: 1 |
当设置
1 2 3 4 5 6 7 8 9 10 11 12 13 | public Random(long seed) { if (getClass() == Random.class) this.seed = new AtomicLong(initialScramble(seed)); else { // subclass might have overriden setSeed this.seed = new AtomicLong(); setSeed(seed); } } private static long initialScramble(long seed) { return (seed ^ multiplier) & mask; // (seed XOR multiplier) AND mask } |
但是,
1 2 | private static final long mask = (1L << 48) - 1; private static final long multiplier = 0x5DEECE66DL; |
由于
输出:
1 2 3 4 5 6 |
以及:
1 2 3 4 5 6 |
另请参见StackOverflow上的这个答案