GitHub
teilweisepackages/random/src

Random

@ralphschuler/random

Vergleicht mehrere deterministische Pseudozufallsstrategien und eine gewichtete Elementauswahl unter einem gemeinsamen API-Modell.

PRNGseedweighted selection

01 · Problem

Wofür braucht man das?

Simulationen und Tests benötigen reproduzierbare Folgen statt des globalen und nicht seedbaren Math.random.

02 · Denkmodell

Das mentale Modell

Ein Seed initialisiert einen endlichen Zustand. Jede Transition produziert einen Integer und den nächsten Zustand; Float- und Bereichsfunktionen sind sichere Abbildungen darauf.

Im Repository

LCG, Lagged Fibonacci, MT, Wichmann-Hill und XORShift sind angelegt. Die Basisklasse ignoriert ihren Seed, Seed-Hexkonvertierung verliert Daten und die Fortuna-Ausgabe bleibt Math.random statt kryptografisch.

03 · Kontrollfluss

Was passiert in welcher Reihenfolge?

  1. Seed auf eine feste, gültige Zustandsbreite normalisieren.
  2. Pro Abruf exakt eine deterministische State-Transition ausführen.
  3. Unsigned Integer in [0, 1) oder ohne Modulo-Bias in einen Integerbereich abbilden.
  4. Gewichtete Auswahl über positive Rohgewichte und kumulative Intervalle ausführen.

04 · Bauteile

Die entscheidenden Verträge

Seed Bufferbasierter Seedcontainer mit fehleranfälliger Hexkonvertierung.
PseudoRandomNumberGenerator Basisklasse für nextFloat und nextInt, nutzt aktuell Math.random.
MersenneTwister / XORShift / weitere Strategien Konkrete Zustandsalgorithmen.
PseudoRandomItemSelector Wählt Items anhand als Prozent interpretierten Gewichten.

05 · Build it yourself

Selbst implementieren

Ein Xorshift32 genügt als kleiner reproduzierbarer Generator; Sicherheit ist ausdrücklich nicht sein Ziel.

  1. Seed als von null verschiedenen uint32 normalisieren.
  2. State ausschließlich über die definierte Bittransition verändern.
  3. Durch 2^32 teilen, damit nextFloat niemals 1 ergibt.
minimal.ts · unabhängig vom Package
class XorShift32 {
  private state: number;
  constructor(seed: number) { this.state = seed >>> 0 || 0x9e3779b9; }

  nextUint32() {
    let value = this.state;
    value ^= value << 13;
    value ^= value >>> 17;
    value ^= value << 5;
    return (this.state = value >>> 0);
  }

  nextFloat() { return this.nextUint32() / 0x1_0000_0000; }
}

06 · Verifizieren

Was du testen solltest

  • Gleiche Seeds liefern über viele Schritte exakt gleiche Folgen.
  • Jeder Float liegt in [0, 1) und jede Integerabbildung im verlangten Bereich.
  • Gewichtete Auswahl lehnt leere, negative, NaN- und vollständig nullgewichtete Listen ab.

07 · Grenzen

Kompromisse und Stolperfallen

  • Kleine PRNGs sind schnell und statistisch begrenzt.
  • Große Zustände verbessern Perioden, machen Snapshot und Restore teurer.
  • Keiner dieser Algorithmen darf für Schlüssel, Tokens oder andere Sicherheitswerte verwendet werden.
Wichtig

Für Kryptografie ausschließlich crypto.getRandomValues oder node:crypto verwenden. Der Name Fortuna im Repository verspricht aktuell eine Sicherheit, die die Implementierung nicht liefert.

08 · Weiterdenken

Quellcode und Nachbarn

Originalcode auf GitHub ansehen