PRNG with seed

Pseudo random number generator with seed

NameState sizeSpeedComment
SplitMix3232-bit10,477,915
Mulberry3232-bit10,440,286Best speed and statistical quality for 32-bit
sfc32128-bit7,451,860Best speed and statistical quality for 128-bit
xoshiro128**128-bit6,930,900Fast and totally acceptable, but poor randomness in the lower bits. fails linear-complexity and binary-rank tests
JSF128-bit6,183,320Well-tested, pretty good.

Resume of bryc in a response on Stack Overflow.
Here more informations : github.com/bryc.
To generate seed you can use cyrb128 (at the bottom of the page).

Other alternative, the Javascript library seedrandom.js

sfc32

/**
 * Pseudo-number generator
 * sfc32 has a 128-bit state and is very fast
 **/
function sfc32(a, b, c, d) {
  return function() {
    a |= 0; b |= 0; c |= 0; d |= 0;
    let t = (a + b | 0) + d | 0;
    d = d + 1 | 0;
    a = b ^ b >>> 9;
    b = c + (c << 3) | 0;
    c = (c << 21 | c >>> 11);
    c = c + t | 0;
    return (t >>> 0) / 4294967296;
  }
}

const seedgen = () => (Math.random()*2**32)>>>0;
const getRand = sfc32(seedgen(), seedgen(), seedgen(), seedgen());
for(let i=0; i<10; i++) console.log(getRand());

SplitMix32

/**
 * Pseudo-number generator
 * One of the better 32-bit PRNGs so far
 **/
function splitmix32(a) {
 return function() {
   a |= 0;
   a = a + 0x9e3779b9 | 0;
   let t = a ^ a >>> 16;
   t = Math.imul(t, 0x21f0aaad);
   t = t ^ t >>> 15;
   t = Math.imul(t, 0x735a2d97);
   return ((t = t ^ t >>> 15) >>> 0) / 4294967296;
  }
}

const prng = splitmix32((Math.random()*2**32)>>>0)
for(let i=0; i<10; i++) console.log(prng());

Mulberry32

/**
 * Pseudo-number generator
 * 32-bit state, but extremely fast with acceptable quality randomness
 **/
function mulberry32(a) {
  return function() {
    let t = a += 0x6D2B79F5;
    t = Math.imul(t ^ t >>> 15, t | 1);
    t ^= t + Math.imul(t ^ t >>> 7, t | 61);
    return ((t ^ t >>> 14) >>> 0) / 4294967296;
  }
}

const getRand = mulberry32((Math.random()*2**32)>>>0)
for(let i=0; i<10; i++) console.log(getRand());

xoshiro128**

/**
 * Pseudo-number generator
 * fastest generator that offers a 128-bit state
 **/
function xoshiro128ss(a, b, c, d) {
  return function() {
    let t = b << 9, r = b * 5;
    r = (r << 7 | r >>> 25) * 9;
    c ^= a;
    d ^= b;
    b ^= c;
    a ^= d;
    c ^= t;
    d = d << 11 | d >>> 21;
    return (r >>> 0) / 4294967296;
  }
}

const seedgen = () => (Math.random()*2**32)>>>0;
const getRand = xoshiro128ss(seedgen(), seedgen(), seedgen(), seedgen());
for (let i = 0; i < 10; i++) console.log(getRand());

JSF

/**
 * Pseudo-number generator
 * quite fast, although not as fast as sfc32
 **/
function jsf32(a, b, c, d) {
  return function() {
    a |= 0; b |= 0; c |= 0; d |= 0;
    let t = a - (b << 27 | b >>> 5) | 0;
    a = b ^ (c << 17 | c >>> 15);
    b = c + d | 0;
    c = d + t | 0;
    d = a + t | 0;
    return (d >>> 0) / 4294967296;
  }
}

const seedgen = () => (Math.random()*2**32)>>>0;
const getRand = jsf32(seedgen(), seedgen(), seedgen(), seedgen());
for (let i = 0; i < 10; i++) console.log(getRand());

cyrb128

/**
 * Generate 128-bit hash for seed
 * Only designed & tested for seed generation,
 * may be suboptimal as a general 128-bit hash.
 **/
function cyrb128(str) {
    let h1 = 1779033703, h2 = 3144134277,
        h3 = 1013904242, h4 = 2773480762;
    for (let i = 0, k; i < str.length; i++) {
        k = str.charCodeAt(i);
        h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
        h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
        h3 = h4 ^ Math.imul(h3 ^ k, 951274213);
        h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);
    }
    h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);
    h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);
    h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);
    h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);
    h1 ^= (h2 ^ h3 ^ h4), h2 ^= h1, h3 ^= h1, h4 ^= h1;
    return [h1>>>0, h2>>>0, h3>>>0, h4>>>0];
}