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  })();