是否有可能在JavaScript中播种随机数生成器(Math.random) ?


当前回答

结合之前的一些答案,这是你正在寻找的可种子随机函数:

Math.seed = function(s) {
    var mask = 0xffffffff;
    var m_w  = (123456789 + s) & mask;
    var m_z  = (987654321 - s) & mask;

    return function() {
      m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
      m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;

      var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
      result /= 4294967296;
      return result;
    }
}

var myRandomFunction = Math.seed(1234);
var randomNumber = myRandomFunction();

其他回答

不,不可能为Math.random()提供种子,但是编写自己的生成器相当容易,或者更好的是使用现有的生成器。

请看:这个相关的问题。

另外,请参阅David Bau的博客了解更多关于播种的信息。

在PHP中,有一个srand(seed)函数,它为特定的seed生成固定的随机值。 但是,在JS中,没有这样的内置函数。

然而,我们可以编写简单而简短的函数。

第一步:选择一些种子(固定编号)。 Var种子= 100; Number应为正整数且大于1,详见步骤2。

第2步:在Seed上执行Math.sin()函数,它将给出该数字的sin值。将这个值存储在变量x中。

var x; 
x = Math.sin(seed); // Will Return Fractional Value between -1 & 1 (ex. 0.4059..)

sin()方法返回一个介于-1到1之间的分数值。我们不需要负数,因此,在第一步中选择大于1的数字。

步骤3:返回值是-1到1之间的分数值。所以这个值乘以10使它大于1。

x = x * 10; // 10 for Single Digit Number

第四步:将数值乘以10,得到额外的数字

x = x * 10; // Will Give value between 10 and 99 OR
x = x * 100; // Will Give value between 100 and 999

按要求的数字相乘。

结果将是十进制的。

第五步:通过Math's Round (Math. Round())方法删除小数点后的值。

x = Math.round(x); // This will give Integer Value.

第六步:用数学把负值转化为正数(如果有的话)。abs方法

x = Math.abs(x); // Convert Negative Values into Positive(if any)

解释。最终代码

var seed = 111; // Any Number greater than 1
var digit = 10 // 1 => single digit, 10 => 2 Digits, 100 => 3 Digits and so. (Multiple of 10) 

var x; // Initialize the Value to store the result
x = Math.sin(seed); // Perform Mathematical Sin Method on Seed.
x = x * 10; // Convert that number into integer
x = x * digit; // Number of Digits to be included
x = Math.round(x); // Remove Decimals
x = Math.abs(x); // Convert Negative Number into Positive

干净和优化的函数代码

function random_seed(seed, digit = 1) {
    var x = Math.abs(Math.round(Math.sin(seed++) * 10 * digit));
    return x;
}

然后调用此函数using Random_seed (any_number, number_of_digits)any_number必须且应该大于1。number_of_digits是可选参数,如果没有传递,将返回1 Digit。

random_seed(555); // 1 Digit
random_seed(234, 1); // 1 Digit
random_seed(7895656, 1000); // 4 Digit

这里的大多数答案都会产生偏颇的结果。这是一个基于github的seerandom库的测试函数:

!function(f,a,c){var s,l=256,p="random",d=c.pow(l,6),g=c.pow(2,52),y=2*g,h=l-1;function n(n,t,r){function e(){for(var n=u.g(6),t=d,r=0;n<g;)n=(n+r)*l,t*=l,r=u.g(1);for(;y<=n;)n/=2,t/=2,r>>>=1;return(n+r)/t}var o=[],i=j(function n(t,r){var e,o=[],i=typeof t;if(r&&"object"==i)for(e in t)try{o.push(n(t[e],r-1))}catch(n){}return o.length?o:"string"==i?t:t+"\0"}((t=1==t?{entropy:!0}:t||{}).entropy?[n,S(a)]:null==n?function(){try{var n;return s&&(n=s.randomBytes)?n=n(l):(n=new Uint8Array(l),(f.crypto||f.msCrypto).getRandomValues(n)),S(n)}catch(n){var t=f.navigator,r=t&&t.plugins;return[+new Date,f,r,f.screen,S(a)]}}():n,3),o),u=new m(o);return e.int32=function(){return 0|u.g(4)},e.quick=function(){return u.g(4)/4294967296},e.double=e,j(S(u.S),a),(t.pass||r||function(n,t,r,e){return e&&(e.S&&v(e,u),n.state=function(){return v(u,{})}),r?(c[p]=n,t):n})(e,i,"global"in t?t.global:this==c,t.state)}function m(n){var t,r=n.length,u=this,e=0,o=u.i=u.j=0,i=u.S=[];for(r||(n=[r++]);e<l;)i[e]=e++;for(e=0;e<l;e++)i[e]=i[o=h&o+n[e%r]+(t=i[e])],i[o]=t;(u.g=function(n){for(var t,r=0,e=u.i,o=u.j,i=u.S;n--;)t=i[e=h&e+1],r=r*l+i[h&(i[e]=i[o=h&o+t])+(i[o]=t)];return u.i=e,u.j=o,r})(l)}function v(n,t){return t.i=n.i,t.j=n.j,t.S=n.S.slice(),t}function j(n,t){for(var r,e=n+"",o=0;o<e.length;)t[h&o]=h&(r^=19*t[h&o])+e.charCodeAt(o++);return S(t)}function S(n){return String.fromCharCode.apply(0,n)}if(j(c.random(),a),"object"==typeof module&&module.exports){module.exports=n;try{s=require("crypto")}catch(n){}}else"function"==typeof define&&define.amd?define(function(){return n}):c["seed"+p]=n}("undefined"!=typeof self?self:this,[],Math);

function randIntWithSeed(seed, max=1) {
  /* returns a random number between [0,max] including zero and max
  seed can be either string or integer */
  return Math.round(new Math.seedrandom('seed' + seed)()) * max
}

测试此代码的真正随机性:https://es6console.com/kkjkgur2/

SIN(id + seed)是一个非常有趣的替代RANDOM函数,不能像SQLite一样播种:

https://stackoverflow.com/a/75089040/7776828

我写了一个函数,返回一个种子随机数,它使用数学。罪恶有一个很长的随机数,并使用种子从其中挑选数字。

使用:

seedRandom("k9]:2@", 15)

它将返回您的种子号码 第一个参数是任意字符串值;你的种子。 第二个参数是返回多少位数字。

     function seedRandom(inputSeed, lengthOfNumber){

           var output = "";
           var seed = inputSeed.toString();
           var newSeed = 0;
           var characterArray = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','y','x','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','U','R','S','T','U','V','W','X','Y','Z','!','@','#','$','%','^','&','*','(',')',' ','[','{',']','}','|',';',':',"'",',','<','.','>','/','?','`','~','-','_','=','+'];
           var longNum = "";
           var counter = 0;
           var accumulator = 0;

           for(var i = 0; i < seed.length; i++){
                var a = seed.length - (i+1);
                for(var x = 0; x < characterArray.length; x++){
                     var tempX = x.toString();
                     var lastDigit = tempX.charAt(tempX.length-1);
                     var xOutput = parseInt(lastDigit);
                     addToSeed(characterArray[x], xOutput, a, i); 
                }                  
           }

                function addToSeed(character, value, a, i){
                     if(seed.charAt(i) === character){newSeed = newSeed + value * Math.pow(10, a)}
                }
                newSeed = newSeed.toString();

                var copy = newSeed;
           for(var i=0; i<lengthOfNumber*9; i++){
                newSeed = newSeed + copy;
                var x = Math.sin(20982+(i)) * 10000;
                var y = Math.floor((x - Math.floor(x))*10);
                longNum = longNum + y.toString()
           }

           for(var i=0; i<lengthOfNumber; i++){
                output = output + longNum.charAt(accumulator);
                counter++;
                accumulator = accumulator + parseInt(newSeed.charAt(counter));
           }
           return(output)
      }