Skip to content

Instantly share code, notes, and snippets.

@graue
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save graue/8261a33341720fe8bc52 to your computer and use it in GitHub Desktop.
Save graue/8261a33341720fe8bc52 to your computer and use it in GitHub Desktop.

Bob Jenkins' small noncryptographic PRNG adapted to JavaScript.

test.js prints 10MB of random bytes to the standard output using Node, useful for benchmarking and testing randomness.

With Node 0.10.28, test.js is on-par in performance with equivalent code using

((1<<31) * 2 * Math.random()) >>> 0

to generate random numbers, and does much better on the chi-square test in ent (the results on ent's other tests do not significantly differ).

This also gives you repeatable "randomness" as you can save the seed you used and reuse that seed later, unlike Math.random.

function BurtlePRNG(seed) {
seed >>>= 0;
var ctx = this.ctx = new Array(4);
ctx[0] = 0xf1ea5eed;
ctx[1] = ctx[2] = ctx[3] = seed;
for (var i = 0; i < 20; i++) {
this.next();
}
return this;
}
function rot(x, k) {
return (x << k) | (x >> (32-k));
}
BurtlePRNG.prototype.next = function() {
var ctx = this.ctx;
var e = (ctx[0] - rot(ctx[1], 27))>>>0;
ctx[0] = (ctx[1] ^ rot(ctx[2], 17))>>>0;
ctx[1] = (ctx[2] + ctx[3])>>>0;
ctx[2] = (ctx[3] + e)>>>0;
ctx[3] = (e + ctx[0])>>>0;
return ctx[3];
}
if (typeof module === 'object') {
module.exports = BurtlePRNG;
}
var BurtlePRNG = require('./BurtlePRNG');
var ranctx = new BurtlePRNG(0x2afdf037);
var dwordsPerBlock = 10;
var blocks = 262144;
var buf = new Buffer(dwordsPerBlock*4);
for (var i = 0; i < blocks; i++) {
for (j = 0; j < dwordsPerBlock; j++) {
buf.writeUInt32LE(ranctx.next(), j*4);
}
process.stdout.write(buf);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment