first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
# seed/normalize
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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.