2013-11-24 23 views
3

我對Java RNG的工作原理非常感興趣。我讀過使用getLong()方法以及getInt()和兩個值,這非常簡單。我對getInt(int n)知道n的價值感興趣。使用getInt(int n)方法獲取Java的RNG種子

由於getInt(n)通常使用 val = bits % n;並重復,直到bits - val + (n-1) >= 0),作爲比特next(31)所以VAL ==比特(模N)

我測試一個暴力破解測試所有更多鈔票一對全等與初始數一個,但這對計算機來說非常漫長而且很難。

關於如何以有效的方式獲得種子的任何其他想法?

+0

「getLong」在哪裏閱讀過?另外,你的意思是第一次調用getInt或任意調用? –

+0

http://stackoverflow.com/questions/15236151/inverse-function-of-javas-random-function 然後調用不帶參數的getInt()2次 – mcat

回答

2

您應該能夠使用反射此:

seed: 25214903916 
mask: 281474976710655 
multiplier: 25214903917 
restored initial seed: 1 

seed設置,該值被擾亂:

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) { 
} 

我的機器上輸出

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 
} 

然而,maskmultiplier只是定義爲:

private static final long mask = (1L << 48) - 1; 
private static final long multiplier = 0x5DEECE66DL; 

由於mask是所有1 S爲最顯著48位,而XOR是可逆的,你可以回到最初的種子,如果(且僅當!)是小於(1L < < 48)的,即2^48:

輸出爲:

Random r = new Random((1L << 48)-1); 

seed: 281449761806738 
mask: 281474976710655 
multiplier: 25214903917 
restored initial seed: 281474976710655 

和用於:

Random r = new Random((1L << 48)); 

seed: 25214903917 
mask: 281474976710655 
multiplier: 25214903917 
restored initial seed: 0 

另請參見this answer on StackOverflow

+0

當你得到結果的種子時不可能推導出原始種子並執行操作? –

+0

讓我檢查一下,如果最初的種子小於2^48,我認爲是可能的。 – jmiserez

+2

請參閱我的關於如何獲得初始種子值的更新答案。 – jmiserez