xorwow.js 1.9 KB

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