Ist es möglich, den Zufallszahlengenerator ( Math.random
) in JavaScript?
Antworten
Zu viele Anzeigen?Hier ist die übernommene Version von Jenkins Hash, entlehnt aus aquí
export function createDeterministicRandom(): () => number {
let seed = 0x2F6E2B1;
return function() {
// Robert Jenkins’ 32 bit integer hash function
seed = ((seed + 0x7ED55D16) + (seed << 12)) & 0xFFFFFFFF;
seed = ((seed ^ 0xC761C23C) ^ (seed >>> 19)) & 0xFFFFFFFF;
seed = ((seed + 0x165667B1) + (seed << 5)) & 0xFFFFFFFF;
seed = ((seed + 0xD3A2646C) ^ (seed << 9)) & 0xFFFFFFFF;
seed = ((seed + 0xFD7046C5) + (seed << 3)) & 0xFFFFFFFF;
seed = ((seed ^ 0xB55A4F09) ^ (seed >>> 16)) & 0xFFFFFFFF;
return (seed & 0xFFFFFFF) / 0x10000000;
};
}
Sie können es so verwenden:
const deterministicRandom = createDeterministicRandom()
deterministicRandom()
// => 0.9872818551957607
deterministicRandom()
// => 0.34880331158638
Die meisten der hier gegebenen Antworten führen zu verzerrten Ergebnissen. Hier ist also eine getestete Funktion, die auf seedrandom Bibliothek von github :
!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
}
Test auf echte Zufälligkeit des Codes: https://es6console.com/kkjkgur2/
Ich habe eine Funktion geschrieben, die eine gesetzte Zufallszahl zurückgibt. Sie verwendet Math.sin, um eine lange Zufallszahl zu erhalten, und verwendet den Seed, um daraus Zahlen auszuwählen.
Verwendung:
seedRandom("k9]:2@", 15)
er gibt die gesetzte Zahl zurück der erste Parameter ist eine beliebige Zeichenkette; Ihr Seed. der zweite Parameter gibt an, wie viele Ziffern zurückgegeben werden sollen.
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)
}
In PHP gibt es die Funktion srand(seed)
die einen festen Zufallswert für einen bestimmten Seed erzeugen. In JS gibt es jedoch keine solche eingebaute Funktion.
Wir können jedoch eine einfache und kurze Funktion schreiben.
Paso 1 : Wählen Sie einige Saatgut (Fixe Nummer).
var seed = 100;
Die Zahl sollte eine positive ganze Zahl und größer als 1 sein, weitere Erläuterungen unter Schritt 2 .
Paso 2 : Durchführen Math.sin() Funktion bei Saatgut gibt es Sinuswert dieser Zahl. Speichern Sie diesen Wert in Variable x .
var x;
x = Math.sin(seed); // Will Return Fractional Value between -1 & 1 (ex. 0.4059..)
sin() Methode gibt einen gebrochenen Wert zwischen -1 und 1 zurück.
Und wir brauchen keinen negativen Wert, also wählen wir im ersten Schritt eine Zahl größer als 1.
Paso 3 : Der zurückgegebene Wert ist ein gebrochener Wert zwischen -1 und 1.
Multiplizieren Sie also diesen Wert mit 10, damit er größer als 1 ist.
x = x * 10; // 10 for Single Digit Number
Paso 4 : Multiplizieren Sie den Wert mit 10 für zusätzliche Ziffern
x = x * 10; // Will Give value between 10 and 99 OR
x = x * 100; // Will Give value between 100 and 999
Multiplizieren Sie je nach Bedarf der Ziffern.
Das Ergebnis wird als Dezimalzahl angezeigt.
Paso 5 : Wert nach dem Dezimalpunkt mit Math's Round entfernen ( Math.round() ) Methode.
x = Math.round(x); // This will give Integer Value.
Paso 6 : Negative Werte in positive umwandeln (falls vorhanden) durch Math.abs Methode
x = Math.abs(x); // Convert Negative Values into Positive(if any)
Erläuterung Ende.
Endgültiger Kodex
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
Sauberer und optimierter Funktionscode
function random_seed(seed, digit = 1) {
var x = Math.abs(Math.round(Math.sin(seed++) * 10 * digit));
return x;
}
Dann rufen Sie diese Funktion mit
random_seed(any_number, number_of_digits)
beliebige_Zahl muss und sollte größer als 1 sein.
Anzahl_der_Ziffern ist ein optionaler Parameter und wenn nichts übergeben wird, wird 1 Digit zurückgegeben.
random_seed(555); // 1 Digit
random_seed(234, 1); // 1 Digit
random_seed(7895656, 1000); // 4 Digit