簡體   English   中英

如何重建Math.random()的種子?

[英]How to reconstruct the seed of Math.random()?

我知道使用Math.random()進行加密是不安全的。 我需要一個重構JavaScript中使用的Math.random()函數的示例代碼來生成隨機數。 例如,如果我有Math.random()生成的隨機數,我怎么能弄清楚種子是什么?

看看來源。 在這種情況下,它位於mozilla / js / src / jsmath.cpp中

static const uint64_t RNG_MULTIPLIER = 0x5DEECE66DLL;
static const uint64_t RNG_ADDEND = 0xBLL;
static const uint64_t RNG_MASK = (1LL << 48) - 1;
static const double RNG_DSCALE = double(1LL << 53);

/*
 * Math.random() support, lifted from java.util.Random.java.
 */

...

extern uint64_t random_next(uint64_t *rngState, int bits)
{
    uint64_t nextstate = *rngState * RNG_MULTIPLIER;
    nextstate += RNG_ADDEND;
    nextstate &= RNG_MASK;
    *rngState = nextstate;
    return nextstate >> (48 - bits);
}

static inline double random_nextDouble(JSContext *cx)
{
    uint64_t *rng = &cx->compartment->rngState;
    return double((random_next(rng, 26) << 27) + random_next(rng, 27)) / RNG_DSCALE;
}

所以,

  1. 調用Math.random()
  2. 乘以2 53得到一個整數n (你要顯式使用uint64_t)
  3. 將其分成RNG輸出的(高位):前26位n>>27 ,后27位n&((1<<27)-1)
  4. 27位可以是第一第二RNG輸出(如C,我不認為C ++這里的一些地方評估順序的任何擔保)。 所以...
    • 迭代2 21個可能的低位。
    • 看看你是否可以通過向前向后運行RNG來到達那里。
    • 如果是,則輸出該數字作為候選。

由於RNG的性質,可能有多個候選者。

向后運行RNG是讀者的練習(您只需要計算0x5DEECE66D模2 48的乘法逆)。 或者,您可以采用26位數字並猜測所有2 22個可能的輸入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM