// A Javascript implementaion of the "Tyche-i" prng algorithm by // Samuel Neves and Filipe Araujo. // See https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf (function(global, module, define) { function XorGen(seed) { var me = this, strseed = ''; // Set up generator function. me.next = function() { var b = me.b, c = me.c, d = me.d, a = me.a; b = (b << 25) ^ (b >>> 7) ^ c; c = (c - d) | 0; d = (d << 24) ^ (d >>> 8) ^ a; a = (a - b) | 0; me.b = b = (b << 20) ^ (b >>> 12) ^ c; me.c = c = (c - d) | 0; me.d = (d << 16) ^ (c >>> 16) ^ a; return me.a = (a - b) | 0; }; /* The following is non-inverted tyche, which has better internal * bit diffusion, but which is about 25% slower than tyche-i in JS. me.next = function() { var a = me.a, b = me.b, c = me.c, d = me.d; a = (me.a + me.b | 0) >>> 0; d = me.d ^ a; d = d << 16 ^ d >>> 16; c = me.c + d | 0; b = me.b ^ c; b = b << 12 ^ d >>> 20; me.a = a = a + b | 0; d = d ^ a; me.d = d = d << 8 ^ d >>> 24; me.c = c = c + d | 0; b = b ^ c; return me.b = (b << 7 ^ b >>> 25); } */ me.a = 0; me.b = 0; me.c = 2654435769 | 0; me.d = 1367130551; if (seed === Math.floor(seed)) { // Integer seed. me.a = (seed / 0x100000000) | 0; me.b = seed | 0; } else { // String seed. strseed += seed; } // Mix in string seed, then discard an initial batch of 64 values. for (var k = 0; k < strseed.length + 20; k++) { me.b ^= strseed.charCodeAt(k) | 0; me.next(); } } function copy(f, t) { t.a = f.a; t.b = f.b; t.c = f.c; 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.tychei = impl; } })( this, (typeof module) == 'object' && module, // present in node.js (typeof define) == 'function' && define // present with an AMD loader );