2.4 KiB
seed/normalize
(no submodules)
Purpose
The normalize module turns a user-supplied seed (number or string) into a uniformly distributed 32-bit unsigned integer suitable for seeding any of the PRNG algorithms in this package. It also exposes the underlying splitmix32/splitmix64 bit-mixers that each algorithm uses internally for seed expansion.
Seed normalisation is the only officially supported way to derive a deterministic starting state; passing the same input twice always returns the same uint32, and distinct inputs are decorrelated by the splitmix64 mixing step.
Features
- Accepts
string | numberseeds; rejectsNaN, infinities and non-safe integers with a typedPseudoRandomError - Deterministic: same input ⇒ same output
- Fast 32-bit bit-mixer (
splitmix32) for scalar mixing - Full 64-bit splitmix state step (
splitmix64) returning{ next, out } expandSeed(seed, n)producesndecorrelated uint32 sub-seeds — used by SFC32 (4 words) and Xoshiro256++ (8 words)
Usage: Basic Example
import { normalizeSeed } from "@suaveplan/pseudo-random/seed";
const seed = normalizeSeed("my-game-state"); // stable uint32
Usage: Advanced Example
import { expandSeed, splitmix64 } from "@suaveplan/pseudo-random/seed";
// Derive 4 sub-seeds for SFC32's 128-bit state from a user key:
const [a, b, c, d] = expandSeed(normalizeSeed("run-7"), 4);
// Or drive the raw bigint stream yourself:
let state = 1n;
for (let i = 0; i < 8; i += 1) {
const { next, out } = splitmix64(state);
state = next;
console.log(out);
}
API Reference
normalizeSeed(seed: string | number): number— returns a uint32.splitmix32(seed: number): number— single mix round, returns a uint32.splitmix64(state: bigint): { next: bigint; out: bigint }— one step of the splitmix64 generator, returned unmasked but kept within the low 64 bits.expandSeed(seed: number, n: number): Uint32Array— n decorrelated sub-seeds.
Implementation Notes
The 32-bit mixer is the classic splitmix avalanche. String inputs are folded into a 32-bit FNV-1a accumulator and then run through splitmix32 to destroy any structural correlation in the input alphabet. Number inputs are converted straight to uint32 (via >>> 0) before mixing — so seed -1 and seed 0xFFFFFFFF are intentionally equivalent. Non-safe integers are rejected because >>> 0 would silently truncate them and lose user intent.