Search code examples
javascriptnode.jsrandomhashprng

JavaScript pseudo-random sequence generator


I need to generate a deterministic (i.e. repeatable) sequence of pseudo-random numbers given an initial seed and select the nth item from that sequence.

If JavaScript's random function was seedable, I could just do:

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

However, it's not, and alternative, seedable PRNGs look to be a little slow; asking for the 250th number would be expensive.

I think a hash is what I want here, perhaps something like md5(seed + seq) % max but JavaScript doesn't have md5() and if I'm doing it in code there's probably a better choice of hash.

I'd like a function where

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

or, ideally

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

Other requirements:

  • must run in node.js and in a browser
  • numbers should be statistically random (or close enough as the period will be small)
  • should be O(1) and reasonably performant

Solution

  • There are some good int -> int hashing functions on this page you can use one of them.

    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 ) );