Verwenden Sie einen Seed, um Zufallszahlen in JavaScript zu generieren

Habdul Hazeez 12 Oktober 2023
  1. Verwenden Sie einen Seed und SFC32, um eine Zufallszahl zu generieren
  2. Verwenden Sie einen Seed und Mulberry32, um eine Zufallszahl zu generieren
  3. Verwenden Sie einen Seed und Xoshiro128**, um eine Zufallszahl zu generieren
  4. Verwenden Sie einen Seed und JSF, um eine Zufallszahl zu generieren
  5. Verwenden Sie seedrandom.js, um eine Zufallszahl zu generieren
Verwenden Sie einen Seed, um Zufallszahlen in JavaScript zu generieren

In diesem Artikel geht es darum, wie man einen Seed verwendet, um Zufallszahlen aus PRNGs zu generieren. In der Zwischenzeit ist es eine bewährte Methode, sicherzustellen, dass der Startwert für die PRNGs eine hohe Entropie aufweist.

Daher verwenden wir eine Hash-Funktion, um den Seed zu generieren. Danach übergeben wir den Seed an den PRNG.

Verwenden Sie einen Seed und SFC32, um eine Zufallszahl zu generieren

SFC32 oder Simple Fast Counter ist ein schnelles PRNG von PractRand (hauptsächlich in C), und es hat eine Implementierung in JavaScript mit einem 128-Bit-Status, und es ist sehr schnell. SFC32 benötigt mindestens einen einzelnen Seed, um die Zufallszahl zu generieren.

Wir generieren diesen Seed mithilfe der Hashing-Funktion, einer JavaScript-Implementierung von MurmurHash3, die eine Anfangszeichenfolge benötigt, um den Seed zu generieren. Als Ergebnis übergeben wir einen String.

Im folgenden Code generieren wir den Seed und übergeben ihn an SFC32, der die Zufallszahl zurückgibt.

Code:

// Define the Murmur3Hash function
function MurmurHash3(string) {
  let i = 0;
  for (i, hash = 1779033703 ^ string.length; i < string.length; i++) {
    let bitwise_xor_from_character = hash ^ string.charCodeAt(i);
    hash = Math.imul(bitwise_xor_from_character, 3432918353);
    hash = hash << 13 | hash >>> 19;
  }
  return () => {
    // Return the hash that you can use as a seed
    hash = Math.imul(hash ^ (hash >>> 16), 2246822507);
    hash = Math.imul(hash ^ (hash >>> 13), 3266489909);
    return (hash ^= hash >>> 16) >>> 0;
  }
}

function SimpleFastCounter32(seed_1, seed_2, seed_3, seed_4) {
  return () => {
    seed_1 >>>= 0;
    seed_2 >>>= 0;
    seed_3 >>>= 0;
    seed_4 >>>= 0;
    let cast32 = (seed_1 + seed_2) | 0;
    seed_1 = seed_2 ^ seed_2 >>> 9;
    seed_2 = seed_3 + (seed_3 << 3) | 0;
    seed_3 = (seed_3 << 21 | seed_3 >>> 11);
    seed_4 = seed_4 + 1 | 0;
    cast32 = cast32 + seed_4 | 0;
    seed_3 = seed_3 + cast32 | 0;
    return (cast32 >>> 0) / 4294967296;
  }
}

let generate_seed = MurmurHash3('String for the Seed Key');
let random_number = SimpleFastCounter32(generate_seed(), generate_seed());
console.log(random_number());
console.log(random_number());

Ausgang:

0.837073584087193
0.3599331611767411

Verwenden Sie einen Seed und Mulberry32, um eine Zufallszahl zu generieren

Mulberry32 ist ebenfalls ein PRNG, jedoch einfacher in der Codestruktur als SFC32. Im Gegensatz zu SFC32, das mindestens einen Seed benötigt.

Wir verwenden MurmurHash3, um den Seed mithilfe einer Zeichenfolge zu generieren. Im folgenden Beispiel generieren wir mit einer for-Schleife und Mulberry32 fünf Zufallszahlen.

Code:

// Define the Murmur3Hash function
function MurmurHash3(string) {
  let i = 0;
  for (i, hash = 1779033703 ^ string.length; i < string.length; i++) {
    let bitwise_xor_from_character = hash ^ string.charCodeAt(i);
    hash = Math.imul(bitwise_xor_from_character, 3432918353);
    hash = hash << 13 | hash >>> 19;
  }
  return () => {
    // Return the hash that you can use as a seed
    hash = Math.imul(hash ^ (hash >>> 16), 2246822507);
    hash = Math.imul(hash ^ (hash >>> 13), 3266489909);
    return (hash ^= hash >>> 16) >>> 0;
  }
}

function Mulberry32(string) {
  return () => {
    let for_bit32_mul = string += 0x6D2B79F5;
    let cast32_one = for_bit32_mul ^ for_bit32_mul >>> 15;
    let cast32_two = for_bit32_mul | 1;
    for_bit32_mul = Math.imul(cast32_one, cast32_two);
    for_bit32_mul ^= for_bit32_mul +
        Math.imul(for_bit32_mul ^ for_bit32_mul >>> 7, for_bit32_mul | 61);
    return ((for_bit32_mul ^ for_bit32_mul >>> 14) >>> 0) / 4294967296;
  }
}

let generate_seed = MurmurHash3('String for the Seed Key');
let random_number = Mulberry32(generate_seed());

for (let i = 0; i < 5; i++) {
  console.log(random_number());
}

Ausgang:

0.13532060221768916
0.8630009586922824
0.53870237339288
0.5237146227154881
0.8748106376733631

Verwenden Sie einen Seed und Xoshiro128**, um eine Zufallszahl zu generieren

Professor Vagna und Blackman haben den Generator Xoshiro128** entwickelt. Der xorshift128 ist eine Familie der Xorshift-PRNGs und der schnellste PRNG.

Wie SFC32 kann Xoshiro128** mindestens einen Seed nehmen, bevor er die Zufallszahl erzeugt. Im folgenden Snippet haben wir den erforderlichen Seed mit MurmiurHash3 erstellt.

Code:

// Define the Murmur3Hash function
function MurmurHash3(string) {
  let i = 0;
  for (i, hash = 1779033703 ^ string.length; i < string.length; i++) {
    let bitwise_xor_from_character = hash ^ string.charCodeAt(i);
    hash = Math.imul(bitwise_xor_from_character, 3432918353);
    hash = hash << 13 | hash >>> 19;
  }
  return () => {
    // Return the hash that you can use as a seed
    hash = Math.imul(hash ^ (hash >>> 16), 2246822507);
    hash = Math.imul(hash ^ (hash >>> 13), 3266489909);
    return (hash ^= hash >>> 16) >>> 0;
  }
}

function Xoshiro128_twostar(seed_1, seed_2, seed_3, seed_4) {
  return () => {
    let t = seed_2 << 9, y = seed_1 * 5;
    y = (y << 7 | y >>> 25) * 9;
    seed_3 ^= seed_1;
    seed_4 ^= seed_2;
    seed_2 ^= seed_3;
    seed_1 ^= seed_4;
    seed_3 ^= t;
    seed_4 = seed_4 << 11 | seed_4 >>> 21;
    return (y >>> 0) / 4294967296;
  }
}

let generate_seed = MurmurHash3('String for the Seed Key');
let random_number = Xoshiro128_twostar(generate_seed(), generate_seed());
console.log(random_number());

Ausgang:

0.6150987280998379

Verwenden Sie einen Seed und JSF, um eine Zufallszahl zu generieren

Bob Jenkins hat den Jenkins Small Fast (JSF) Generator entwickelt, einen schnellen Generator. Allerdings ist es im Vergleich zu SFC32 nicht schnell.

Wenn Sie den Code von JSF betrachten, werden Sie Ähnlichkeiten zu SFC32 erkennen. JSF kann mehr als einen Seed nehmen, bevor es eine Zufallszahl produziert.

Wir generieren zehn Zufallszahlen mit einem Seed und JSF im nächsten Code.

Code:

// Define the Murmur3Hash function
function MurmurHash3(string) {
  let i = 0;
  for (i, hash = 1779033703 ^ string.length; i < string.length; i++) {
    let bitwise_xor_from_character = hash ^ string.charCodeAt(i);
    hash = Math.imul(bitwise_xor_from_character, 3432918353);
    hash = hash << 13 | hash >>> 19;
  }
  return () => {
    // Return the hash that you can use as a seed
    hash = Math.imul(hash ^ (hash >>> 16), 2246822507);
    hash = Math.imul(hash ^ (hash >>> 13), 3266489909);
    return (hash ^= hash >>> 16) >>> 0;
  }
}

function JenkinsSimpleFast32(seed_1, seed_2, seed_3, seed_4) {
  return () => {
    seed_1 |= 0;
    seed_2 |= 0;
    seed_3 |= 0;
    seed_4 |= 0;
    let t = seed_1 - (seed_2 << 27 | seed_2 >>> 5) | 0;
    seed_1 = seed_2 ^ (seed_3 << 17 | seed_3 >>> 15);
    seed_2 = seed_3 + seed_4 | 0;
    seed_3 = seed_4 + t | 0;
    seed_4 = seed_1 + t | 0;
    return (seed_4 >>> 0) / 4294967296;
  }
}

let generate_seed = MurmurHash3('String for the Seed Key');
let random_number = JenkinsSimpleFast32(generate_seed(), generate_seed());
for (let i = 0; i < 10; i++) {
  console.log(random_number());
}

Ausgang:

0.513338076416403
0.4737987464759499
0.5743723993655294
0.4811882192734629
0.07753282226622105
0.11416710214689374
0.1270705321803689
0.15759771666489542
0.16906401910819113
0.6846413582097739

Verwenden Sie seedrandom.js, um eine Zufallszahl zu generieren

seedrandom.js ist eine Bibliothek von David Bau, die für Seed Random Number Generator (RNG) entwickelt wurde und auf NPM und CDNJS verfügbar ist. Für diesen Artikel verwenden wir CDNJS.

Beachten Sie bei der Verwendung von Seedrandom.js Folgendes.

  1. Sie initialisieren seedrandom mit new Math.seedrandom('seed key').
  2. Sie können die quick()-Funktion von Seedrandom verwenden, um 32-Bit-Zufälligkeit zu erzeugen.
  3. Die Funktion int32() von Seedrandom.js gibt eine 32-Bit-Ganzzahl mit Vorzeichen zurück.
  4. Der Aufruf von seedrandom ohne Argumente bewirkt die Erstellung eines automatisch gesetzten ARC4-basierten PRNG. Das automatische Seeding verwendet einige Werte wie die akkumulierte lokale Entropie.
  5. Seedrandom kann ein Objekt als zweites Argument annehmen. Dieses Objekt ist {entropy: true}, und das Ergebnis ist unvorhersehbar.
  6. Der Aufruf von Math.seedrandom ohne das Schlüsselwort new ersetzt den Standardwert Math.random(). Der Ersatz ist new Math.seedrandom().

In diesem Beispiel haben wir seedrandom.js von CDNJS importiert. Anschließend verwenden wir es, um mithilfe eines Seeds eine Zufallszahl zu generieren.

Code:

<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js"></script>
    <script>
        let generate_random_number = new Math.seedrandom('Johnson');
        console.log(generate_random_number());
    </script>
</body>

Ausgang:

0.08103389758898699

Sie können Ihren Samen mit der angesammelten Entropie mischen. Sie müssen {entropy: true} als zweites Argument von seedrandom übergeben.

Code:

<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js"></script>
    <script>
        let generate_random_number = new Math.seedrandom('Antananarivo', { entropy: true });
        for (let i = 0; i < 5; i++) {
            console.log(generate_random_number());
        }
    </script>
</body>

Ausgang:

0.8478730572111559
0.963664252064149
0.6002684820777331
0.4026776455839767
0.7579996916288508

Zusätzlich geben quick() und int32() zufällige 32-Bit-Zufallszahlen zurück. Ersteres gibt einen Float zurück, während letzteres eine vorzeichenbehaftete Ganzzahl zurückgibt.

Code:

<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js"></script>
    <script>
        let generate_random_number = new Math.seedrandom('DavidBau');
        console.log("With quick():", generate_random_number.quick());
        console.log("With int32():", generate_random_number.int32());
    </script>
</body>

Ausgang:

With quick(): 0.249648863915354
With int32(): -550219731
Habdul Hazeez avatar Habdul Hazeez avatar

Habdul Hazeez is a technical writer with amazing research skills. He can connect the dots, and make sense of data that are scattered across different media.

LinkedIn

Verwandter Artikel - JavaScript Number