# `recovery/generate` ## Purpose Generate Crockford-base32 recovery codes — the printable single-use fallback the user prints / writes down when first enrolling MFA. Default form is the conventional `XXXX-XXXX-XXXX-XXXX` quad-grouped 16-character shape. RNG is injectable so deterministic test fixtures can produce stable byte strings; production callers leave it default and pull from the platform CSPRNG. ## Features - Crockford alphabet (excludes `I`, `L`, `O`, `U` to avoid hand-copy collisions with `1` / `0`). - Configurable length / group size / separator. - Injectable `Rng` (`@suaveplan/types`) — `nextBytes` preferred, falls back to `nextUint32` assembly. - Default RNG draws from `randomBytes` in `@suaveplan/crypto-utils`. ## Usage: Basic Example ```ts import { generateRecoveryCodes } from "@suaveplan/otp"; const codes = generateRecoveryCodes(10); // ten codes shaped like "XXXX-XXXX-XXXX-XXXX". ``` ## Usage: Advanced Example ```ts import { generateRecoveryCodes } from "@suaveplan/otp"; // Custom form for a UI that accepts longer codes. const codes = generateRecoveryCodes(5, { length: 20, groupSize: 5, separator: " ", }); ``` ## API Reference - `generateRecoveryCodes(count, opts?): string[]` — primary API. - `bytesFromRng(rng, n): Uint8Array` — exported helper used by the recovery-hash module to draw salt bytes from the same RNG. - `RecoveryCodeOptions` — `{ length?: number; groupSize?: number; separator?: string; rng?: Rng }`. ## Implementation Notes The 32-character alphabet is power-of-two sized so taking `byte & 0x1f` introduces no modulo bias. When the supplied `Rng` only exposes `nextUint32`, the helper assembles bytes from 32-bit words and uses guarded indexing so a request for `n < 4` writes only the bytes the caller asked for. The default RNG is the platform CSPRNG via `@suaveplan/crypto-utils` — bring your own only for deterministic tests. Crockford-base32's character exclusions (`I`, `L`, `O`, `U`) are the practical reason this module does not reuse the standard RFC 4648 alphabet exposed by the `base32` module: hand-copied recovery codes get transcribed under stress, and visually-similar characters cause silent enrollment errors. The two alphabets are distinct on purpose and must not be confused when implementing import / export between password managers.