87 lines
1.9 KiB
JavaScript
87 lines
1.9 KiB
JavaScript
|
// A Javascript implementaion of the "xorwow" prng algorithm by
|
||
|
// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper
|
||
|
|
||
|
(function(global, module, define) {
|
||
|
|
||
|
function XorGen(seed) {
|
||
|
var me = this, strseed = '';
|
||
|
|
||
|
// Set up generator function.
|
||
|
me.next = function() {
|
||
|
var t = (me.x ^ (me.x >>> 2));
|
||
|
me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v;
|
||
|
return (me.d = (me.d + 362437 | 0)) +
|
||
|
(me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0;
|
||
|
};
|
||
|
|
||
|
me.x = 0;
|
||
|
me.y = 0;
|
||
|
me.z = 0;
|
||
|
me.w = 0;
|
||
|
me.v = 0;
|
||
|
|
||
|
if (seed === (seed | 0)) {
|
||
|
// Integer seed.
|
||
|
me.x = seed;
|
||
|
} else {
|
||
|
// String seed.
|
||
|
strseed += seed;
|
||
|
}
|
||
|
|
||
|
// Mix in string seed, then discard an initial batch of 64 values.
|
||
|
for (var k = 0; k < strseed.length + 64; k++) {
|
||
|
me.x ^= strseed.charCodeAt(k) | 0;
|
||
|
if (k == strseed.length) {
|
||
|
me.d = me.x << 10 ^ me.x >>> 4;
|
||
|
}
|
||
|
me.next();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function copy(f, t) {
|
||
|
t.x = f.x;
|
||
|
t.y = f.y;
|
||
|
t.z = f.z;
|
||
|
t.w = f.w;
|
||
|
t.v = f.v;
|
||
|
t.d = f.d;
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
function impl(seed, opts) {
|
||
|
var xg = new XorGen(seed),
|
||
|
state = opts && opts.state,
|
||
|
prng = function() { return (xg.next() >>> 0) / 0x100000000; };
|
||
|
prng.double = function() {
|
||
|
do {
|
||
|
var top = xg.next() >>> 11,
|
||
|
bot = (xg.next() >>> 0) / 0x100000000,
|
||
|
result = (top + bot) / (1 << 21);
|
||
|
} while (result === 0);
|
||
|
return result;
|
||
|
};
|
||
|
prng.int32 = xg.next;
|
||
|
prng.quick = prng;
|
||
|
if (state) {
|
||
|
if (typeof(state) == 'object') copy(state, xg);
|
||
|
prng.state = function() { return copy(xg, {}); }
|
||
|
}
|
||
|
return prng;
|
||
|
}
|
||
|
|
||
|
if (module && module.exports) {
|
||
|
module.exports = impl;
|
||
|
} else if (define && define.amd) {
|
||
|
define(function() { return impl; });
|
||
|
} else {
|
||
|
this.xorwow = impl;
|
||
|
}
|
||
|
|
||
|
})(
|
||
|
this,
|
||
|
(typeof module) == 'object' && module, // present in node.js
|
||
|
(typeof define) == 'function' && define // present with an AMD loader
|
||
|
);
|
||
|
|
||
|
|