/** * Feistel index permutation — a "lottery with no tumbler". * * A keyed pseudo-random **bijection** on `[0, n)`: `permute(i, n, key)` maps * each row index to a unique, scrambled "slot" without ever building an * array. This is what lets the streaming engine place a sorted quota plan * (`[A×70%, B×30%]`) into random-looking positions and get EXACT percentages * — because a bijection sends exactly `0.7n` indices into the first `0.7n` * slots — with O(1) memory and O(1) per row. * * Construction: a balanced Feistel network on the smallest `2^(2·half) ≥ n`, * with **cycle-walking** to fold the domain back down to exactly `[0, n)` for * non-power-of-two `n` (re-apply until the result is in range; expected < 4 * iterations since the padded domain is < 4n). `unpermute` is the inverse * (needed by uniq's mixed-radix decode later). * * Determinism is cross-language: the round function uses only `Math.imul` and * 32-bit ops, and the key comes from cyrb128. Combining halves uses plain * arithmetic (not bit-shifts) so it stays exact for `n` up to ~2^52. */ /** Derive a 32-bit round key for a permutation stream. */ export declare function permuteKey(seed: string, streamId: string): number; /** Bijection `[0, n) → [0, n)`: the scrambled slot for row `index`. */ export declare function permute(index: number, n: number, key: number): number; /** Inverse of `permute`: the row index that maps to `slot`. */ export declare function unpermute(slot: number, n: number, key: number): number; //# sourceMappingURL=permute.d.ts.map