github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/v8/lib/1.0.5/random.js (about) 1 // Copyright (C) 2018 go-nebulas 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // the go-nebulas library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with the go-nebulas library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 19 // A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010 20 // http://baagoe.com/en/RandomMusings/javascript/ 21 // https://github.com/nquinlan/better-random-numbers-for-javascript-mirror 22 // Original work is under MIT license - 23 24 // Other seeded random number generators for JavaScript, see https://github.com/davidbau/seedrandom. 25 26 27 'use strict'; 28 29 function Alea(seed) { 30 var me = this, mash = Mash(); 31 32 me.next = function () { 33 var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32 34 me.s0 = me.s1; 35 me.s1 = me.s2; 36 return me.s2 = t - (me.c = t | 0); 37 }; 38 39 // Apply the seeding algorithm from Baagoe. 40 me.c = 1; 41 me.s0 = mash(' '); 42 me.s1 = mash(' '); 43 me.s2 = mash(' '); 44 me.s0 -= mash(seed); 45 if (me.s0 < 0) { me.s0 += 1; } 46 me.s1 -= mash(seed); 47 if (me.s1 < 0) { me.s1 += 1; } 48 me.s2 -= mash(seed); 49 if (me.s2 < 0) { me.s2 += 1; } 50 mash = null; 51 } 52 53 function copy(f, t) { 54 t.c = f.c; 55 t.s0 = f.s0; 56 t.s1 = f.s1; 57 t.s2 = f.s2; 58 return t; 59 } 60 61 function impl(seed, opts) { 62 var xg = new Alea(seed), 63 state = opts && opts.state, 64 prng = xg.next; 65 prng.int32 = function () { return (xg.next() * 0x100000000) | 0; } 66 prng.double = function () { 67 return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53 68 }; 69 prng.quick = prng; 70 if (state) { 71 if (typeof (state) == 'object') copy(state, xg); 72 prng.state = function () { return copy(xg, {}); } 73 } 74 return prng; 75 } 76 77 function Mash() { 78 var n = 0xefc8249d; 79 80 var mash = function (data) { 81 data = data.toString(); 82 for (var i = 0; i < data.length; i++) { 83 n += data.charCodeAt(i); 84 var h = 0.02519603282416938 * n; 85 n = h >>> 0; 86 h -= n; 87 h *= n; 88 n = h >>> 0; 89 h -= n; 90 n += h * 0x100000000; // 2^32 91 } 92 return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 93 }; 94 95 return mash; 96 } 97 98 module.exports = (function(){ 99 100 var arng = null; 101 102 function checkCtx() { 103 if (!Blockchain) { 104 throw new Error("'Blockchain' is undefined."); 105 } 106 if (!Blockchain.block) { 107 throw new Error("'Blockchain.block' is undefined."); 108 } 109 110 if (Blockchain.block.seed == null || typeof(Blockchain.block.seed) === 'undefined') { 111 throw new Error("Math.random func is not allowed in nvm."); 112 } 113 } 114 115 function rand() { 116 if (arng == null) { 117 checkCtx(); 118 arng = new impl(Blockchain.block.seed); 119 } 120 return arng(); 121 } 122 rand.seed = function(userseed) { 123 if (typeof(userseed) !== 'string') { 124 throw new Error("input seed must be a string") 125 } 126 if (userseed === "") { 127 return; 128 } 129 checkCtx(); 130 arng = new impl(Blockchain.block.seed + userseed); 131 } 132 133 return rand; 134 })();