xorshift7.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // A Javascript implementaion of the "xorshift7" algorithm by
  2. // François Panneton and Pierre L'ecuyer:
  3. // "On the Xorgshift Random Number Generators"
  4. // http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf
  5. (function(global, module, define) {
  6. function XorGen(seed) {
  7. var me = this;
  8. // Set up generator function.
  9. me.next = function() {
  10. // Update xor generator.
  11. var X = me.x, i = me.i, t, v, w;
  12. t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24);
  13. t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10);
  14. t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3);
  15. t = X[(i + 4) & 7]; v ^= t ^ (t << 7);
  16. t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9);
  17. X[i] = v;
  18. me.i = (i + 1) & 7;
  19. return v;
  20. };
  21. function init(me, seed) {
  22. var j, w, X = [];
  23. if (seed === (seed | 0)) {
  24. // Seed state array using a 32-bit integer.
  25. w = X[0] = seed;
  26. } else {
  27. // Seed state using a string.
  28. seed = '' + seed;
  29. for (j = 0; j < seed.length; ++j) {
  30. X[j & 7] = (X[j & 7] << 15) ^
  31. (seed.charCodeAt(j) + X[(j + 1) & 7] << 13);
  32. }
  33. }
  34. // Enforce an array length of 8, not all zeroes.
  35. while (X.length < 8) X.push(0);
  36. for (j = 0; j < 8 && X[j] === 0; ++j);
  37. if (j == 8) w = X[7] = -1; else w = X[j];
  38. me.x = X;
  39. me.i = 0;
  40. // Discard an initial 256 values.
  41. for (j = 256; j > 0; --j) {
  42. me.next();
  43. }
  44. }
  45. init(me, seed);
  46. }
  47. function copy(f, t) {
  48. t.x = f.x.slice();
  49. t.i = f.i;
  50. return t;
  51. }
  52. function impl(seed, opts) {
  53. if (seed == null) seed = +(new Date);
  54. var xg = new XorGen(seed),
  55. state = opts && opts.state,
  56. prng = function() { return (xg.next() >>> 0) / 0x100000000; };
  57. prng.double = function() {
  58. do {
  59. var top = xg.next() >>> 11,
  60. bot = (xg.next() >>> 0) / 0x100000000,
  61. result = (top + bot) / (1 << 21);
  62. } while (result === 0);
  63. return result;
  64. };
  65. prng.int32 = xg.next;
  66. prng.quick = prng;
  67. if (state) {
  68. if (state.x) copy(state, xg);
  69. prng.state = function() { return copy(xg, {}); }
  70. }
  71. return prng;
  72. }
  73. if (module && module.exports) {
  74. module.exports = impl;
  75. } else if (define && define.amd) {
  76. define(function() { return impl; });
  77. } else {
  78. this.xorshift7 = impl;
  79. }
  80. })(
  81. this,
  82. (typeof module) == 'object' && module, // present in node.js
  83. (typeof define) == 'function' && define // present with an AMD loader
  84. );