alea.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010
  2. // http://baagoe.com/en/RandomMusings/javascript/
  3. // https://github.com/nquinlan/better-random-numbers-for-javascript-mirror
  4. // Original work is under MIT license -
  5. // Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>
  6. //
  7. // Permission is hereby granted, free of charge, to any person obtaining a copy
  8. // of this software and associated documentation files (the "Software"), to deal
  9. // in the Software without restriction, including without limitation the rights
  10. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the Software is
  12. // furnished to do so, subject to the following conditions:
  13. //
  14. // The above copyright notice and this permission notice shall be included in
  15. // all copies or substantial portions of the Software.
  16. //
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. // THE SOFTWARE.
  24. (function(global, module, define) {
  25. function Alea(seed) {
  26. var me = this, mash = Mash();
  27. me.next = function() {
  28. var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32
  29. me.s0 = me.s1;
  30. me.s1 = me.s2;
  31. return me.s2 = t - (me.c = t | 0);
  32. };
  33. // Apply the seeding algorithm from Baagoe.
  34. me.c = 1;
  35. me.s0 = mash(' ');
  36. me.s1 = mash(' ');
  37. me.s2 = mash(' ');
  38. me.s0 -= mash(seed);
  39. if (me.s0 < 0) { me.s0 += 1; }
  40. me.s1 -= mash(seed);
  41. if (me.s1 < 0) { me.s1 += 1; }
  42. me.s2 -= mash(seed);
  43. if (me.s2 < 0) { me.s2 += 1; }
  44. mash = null;
  45. }
  46. function copy(f, t) {
  47. t.c = f.c;
  48. t.s0 = f.s0;
  49. t.s1 = f.s1;
  50. t.s2 = f.s2;
  51. return t;
  52. }
  53. function impl(seed, opts) {
  54. var xg = new Alea(seed),
  55. state = opts && opts.state,
  56. prng = xg.next;
  57. prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }
  58. prng.double = function() {
  59. return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
  60. };
  61. prng.quick = prng;
  62. if (state) {
  63. if (typeof(state) == 'object') copy(state, xg);
  64. prng.state = function() { return copy(xg, {}); }
  65. }
  66. return prng;
  67. }
  68. function Mash() {
  69. var n = 0xefc8249d;
  70. var mash = function(data) {
  71. data = data.toString();
  72. for (var i = 0; i < data.length; i++) {
  73. n += data.charCodeAt(i);
  74. var h = 0.02519603282416938 * n;
  75. n = h >>> 0;
  76. h -= n;
  77. h *= n;
  78. n = h >>> 0;
  79. h -= n;
  80. n += h * 0x100000000; // 2^32
  81. }
  82. return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
  83. };
  84. return mash;
  85. }
  86. if (module && module.exports) {
  87. module.exports = impl;
  88. } else if (define && define.amd) {
  89. define(function() { return impl; });
  90. } else {
  91. this.alea = impl;
  92. }
  93. })(
  94. this,
  95. (typeof module) == 'object' && module, // present in node.js
  96. (typeof define) == 'function' && define // present with an AMD loader
  97. );