JavaScript伪随机序列生成器

时间:2011-08-25 09:51:54

标签: javascript node.js random hash prng

我需要在给定初始种子的情况下生成pseudo-random个数字的确定性(即可重复)序列,并从该序列中选择第n个项目。

如果JavaScript的随机函数是可播种的,我可以这样做:

function randomNth(seed, seq)
{
    var r;
    Math.randomSeed(seed);
    for (var i = 0; i++ < seq; i++)
    {
        r = Math.random();
    }
    return r;
}

然而,它不是,而另类,可播种的PRNG看起来有点慢;要求第250个数字将是昂贵的。

我认为散列是我想要的,也许类似于md5(seed + seq) % max,但JavaScript没有md5(),如果我在代码中执行它,那么可能有更好的散列选择。

我想要一个

的功能

x = randomNth(seed, seq, maxVal) // x is int && x >= 0 && x < maxVal

或者,理想情况下

x = randomNth(seed, seq) // x >= 0 && x < 1, same as Math.random()

其他要求:

  • 必须在node.js和浏览器中运行
  • 数字应该是统计上随机的(或者足够接近,因为时间段会很小)
  • 应为O(1)且性能合理

4 个答案:

答案 0 :(得分:2)

有一些好的int - &gt; this page上的int散列函数可以使用其中一个。

function hash(a)
{
    a = (a+0x7ed55d16) + (a<<12);
    a = (a^0xc761c23c) ^ (a>>19);
    a = (a+0x165667b1) + (a<<5);
    a = (a+0xd3a2646c) ^ (a<<9);
    a = (a+0xfd7046c5) + (a<<3);
    a = (a^0xb55a4f09) ^ (a>>16);
    if( a < 0 ) a = 0xffffffff + a;
    return a;
}
var seed = 26254;
var index = 250;
alert( hash( seed + index ) );

答案 1 :(得分:2)

最后我使用了(非SO)朋友的建议。我使用了CRC32(),因为它非常快,并提供了相当随机的值。

return crc32(seq + seed) % maxVal;

800万的运行产生了以下maxVal = 8的分布:

  

0 999998

     

1 999998

     

2       1000007

     

3       1000003

     

4       1000001

     

5       1000003

     

6       999992

     

7       999998

我还在汉斯提到的Donald Knuth页面中提到了“Marsaglia's famous "Die Hard" battery of tests”,其结果如下:CRC32() for random numbers Diehard results。简短的版本是它失败了(对于如此少量的测试数据),但它仍然足以满足我的需求,它在小范围内生成数字。

答案 2 :(得分:1)

Donald Knuth可能会有所帮助:http://www-cs-faculty.stanford.edu/~uno/news02.html#rng

答案 3 :(得分:1)