xorwow.js (1919B)
1 // A Javascript implementaion of the "xorwow" prng algorithm by 2 // George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper 3 4 (function(global, module, define) { 5 6 function XorGen(seed) { 7 var me = this, strseed = ''; 8 9 // Set up generator function. 10 me.next = function() { 11 var t = (me.x ^ (me.x >>> 2)); 12 me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v; 13 return (me.d = (me.d + 362437 | 0)) + 14 (me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0; 15 }; 16 17 me.x = 0; 18 me.y = 0; 19 me.z = 0; 20 me.w = 0; 21 me.v = 0; 22 23 if (seed === (seed | 0)) { 24 // Integer seed. 25 me.x = seed; 26 } else { 27 // String seed. 28 strseed += seed; 29 } 30 31 // Mix in string seed, then discard an initial batch of 64 values. 32 for (var k = 0; k < strseed.length + 64; k++) { 33 me.x ^= strseed.charCodeAt(k) | 0; 34 if (k == strseed.length) { 35 me.d = me.x << 10 ^ me.x >>> 4; 36 } 37 me.next(); 38 } 39 } 40 41 function copy(f, t) { 42 t.x = f.x; 43 t.y = f.y; 44 t.z = f.z; 45 t.w = f.w; 46 t.v = f.v; 47 t.d = f.d; 48 return t; 49 } 50 51 function impl(seed, opts) { 52 var xg = new XorGen(seed), 53 state = opts && opts.state, 54 prng = function() { return (xg.next() >>> 0) / 0x100000000; }; 55 prng.double = function() { 56 do { 57 var top = xg.next() >>> 11, 58 bot = (xg.next() >>> 0) / 0x100000000, 59 result = (top + bot) / (1 << 21); 60 } while (result === 0); 61 return result; 62 }; 63 prng.int32 = xg.next; 64 prng.quick = prng; 65 if (state) { 66 if (typeof(state) == 'object') copy(state, xg); 67 prng.state = function() { return copy(xg, {}); } 68 } 69 return prng; 70 } 71 72 if (module && module.exports) { 73 module.exports = impl; 74 } else if (define && define.amd) { 75 define(function() { return impl; }); 76 } else { 77 this.xorwow = impl; 78 } 79 80 })( 81 this, 82 (typeof module) == 'object' && module, // present in node.js 83 (typeof define) == 'function' && define // present with an AMD loader 84 ); 85 86