# 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 | number` seeds; rejects `NaN`, infinities and non-safe integers with a typed `PseudoRandomError` - 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)` produces `n` decorrelated uint32 sub-seeds — used by SFC32 (4 words) and Xoshiro256++ (8 words) ## Usage: Basic Example ```ts import { normalizeSeed } from "@suaveplan/pseudo-random/seed"; const seed = normalizeSeed("my-game-state"); // stable uint32 ``` ## Usage: Advanced Example ```ts 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.