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.
Bietet reproduzierbare Seed-Generatoren und normalisierte gewichtete Auswahl. Fortuna ist ein Kompatibilitätsname für node:crypto, keine Fortuna-Implementierung. Seed-Strategien dienen Simulationen; die Redis-Skizze ist eine explizit nicht unterstützte Integration.
03 · Kontrollfluss
Was passiert in welcher Reihenfolge?
- Seed auf eine feste, gültige Zustandsbreite normalisieren.
- Pro Abruf exakt eine deterministische State-Transition ausführen.
- Unsigned Integer in [0, 1) oder ohne Modulo-Bias in einen Integerbereich abbilden.
- Gewichtete Auswahl über positive Rohgewichte und kumulative Intervalle ausführen.
04 · Bauteile
Die entscheidenden Verträge
Seed / PseudoRandomNumberGeneratorRepräsentiert Seedbytes und reproduzierbare Zahlenfolgen.LinearCongruential / XORShift / MersenneTwister / WichmannHill / LaggedFibonacciWählt eine Strategie für Simulationszufall.Fortuna / PseudoRandomItemSelectorNutzt Betriebssystemzufall über eine Kompatibilitätsfassade oder wählt gewichtete Elemente.05 · Selbst bauen
Selbst implementieren
Ein Xorshift32 genügt als kleiner reproduzierbarer Generator; Sicherheit ist ausdrücklich nicht sein Ziel.
- Seed als von null verschiedenen uint32 normalisieren.
- State ausschließlich über die definierte Bittransition verändern.
- Durch 2^32 teilen, damit nextFloat niemals 1 ergibt.
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 solltest du testen?
- 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.
Selbst ausprobieren
Formuliere die erste Prüfaussage als fehlschlagenden Test, implementiere die kleinste Korrektur und ergänze einen Grenzfall.
Gleiche Seeds liefern über viele Schritte exakt gleiche Folgen.
Ansatz vergleichen
Dein Test sollte beim gezielten Verletzen der Invariante fehlschlagen und nach der Korrektur wieder bestehen. Halte den Aufbau deterministisch und prüfe ein beobachtbares Ergebnis.
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.
Fortuna ist ein Kompatibilitätsname für node:crypto, keine Fortuna-Implementierung. Seed-Strategien dienen Simulationen; die Redis-Skizze ist eine explizit nicht unterstützte Integration.
08 · Weiterdenken
Quellcode und verwandte Ideen
yarn tsx packages/random/examples/basic.ts