Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@opensourceframework/seeded-rng

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@opensourceframework/seeded-rng - npm Package Compare versions

Comparing version
0.1.1
to
0.1.2
+4
-5
package.json
{
"name": "@opensourceframework/seeded-rng",
"version": "0.1.1",
"version": "0.1.2",
"description": "Seeded random number generator for reproducible randomness - NOT cryptographically secure",

@@ -58,9 +58,8 @@ "keywords": [

"type": "git",
"url": "git+https://github.com/riceharvest/opensourceframework.git",
"directory": "packages/seeded-rng"
"url": "git+https://github.com/riceharvest/seeded-rng.git"
},
"bugs": {
"url": "https://github.com/riceharvest/opensourceframework/issues?q=is%3Aissue+is%3Aopen+seeded-rng"
"url": "https://github.com/riceharvest/seeded-rng/issues"
},
"homepage": "https://github.com/riceharvest/opensourceframework/tree/main/packages/seeded-rng#readme",
"homepage": "https://github.com/riceharvest/seeded-rng#readme",
"publishConfig": {

@@ -67,0 +66,0 @@ "access": "public"

'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
/**
* @opensourceframework/seeded-rng
* Seeded random number generator for reproducible randomness
*
* ⚠️ WARNING: This is NOT cryptographically secure!
* Do NOT use for security-sensitive operations like:
* - Password generation
* - Cryptographic keys
* - Session tokens
* - Any security-related randomness
*
* Use crypto.getRandomValues() or Node.js crypto module instead.
*
* @license MIT
*/
// src/index.ts
var SeededRNG = class _SeededRNG {
seed;
initialSeed;
iterations = 0;
// LCG parameters (using values from Numerical Recipes)
static A = 9301;
static C = 49297;
static M = 233280;
/**
* Creates a new seeded RNG instance
*
* @param seed - Optional seed value. If not provided, generates a random seed
*
* @example
* ```typescript
* // With a specific seed (reproducible)
* const rng1 = new SeededRNG(42);
*
* // Without seed (random each time)
* const rng2 = new SeededRNG();
* ```
*/
constructor(seed) {
this.initialSeed = seed ?? Math.floor(Math.random() * 2147483647);
this.seed = this.initialSeed;
}
/**
* Gets the initial seed value (useful for serialization/replay)
*/
getInitialSeed() {
return this.initialSeed;
}
/**
* Gets the current seed/state value
*/
getCurrentSeed() {
return this.seed;
}
/**
* Sets the current seed/state
*/
setSeed(seed) {
this.seed = seed;
}
/**
* Gets statistics about the RNG state
*/
getStats() {
return {
initialSeed: this.initialSeed,
currentSeed: this.seed,
iterations: this.iterations
};
}
/**
* Resets the RNG to its initial state
*/
reset() {
this.seed = this.initialSeed;
this.iterations = 0;
}
/**
* Generates the next random float between 0 (inclusive) and 1 (exclusive)
* Uses LCG algorithm: seed = (seed * a + c) % m
*/
next() {
this.seed = (this.seed * _SeededRNG.A + _SeededRNG.C) % _SeededRNG.M;
this.iterations++;
return this.seed / _SeededRNG.M;
}
/**
* Generates a random integer in range [min, max] (inclusive)
* @throws {Error} If min is greater than max
*/
nextInt(min, max) {
if (min > max) {
throw new Error("min must be less than or equal to max");
}
return Math.floor(this.next() * (max - min + 1)) + min;
}
/**
* Generates a random float in range [min, max)
* @throws {Error} If min is greater than max
*/
nextFloat(min, max) {
if (min > max) {
throw new Error("min must be less than max");
}
return this.next() * (max - min) + min;
}
/**
* Returns true with the given probability (0-1)
*/
chance(probability) {
return this.next() < probability;
}
/**
* Selects a random element from an array
*/
pick(array) {
if (array.length === 0) return void 0;
return array[this.nextInt(0, array.length - 1)];
}
/**
* Shuffles an array using the Fisher-Yates algorithm
*/
shuffle(array) {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = this.nextInt(0, i);
const temp = result[i];
result[i] = result[j];
result[j] = temp;
}
return result;
}
/**
* Selects a random element based on weights
*/
weightedPick(items) {
if (items.length === 0) return void 0;
const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);
let random = this.next() * totalWeight;
for (const item of items) {
random -= item.weight;
if (random <= 0) {
return item.item;
}
}
return items[items.length - 1]?.item;
}
/**
* Generates a random boolean value
*/
nextBool(probability = 0.5) {
return this.chance(probability);
}
/**
* Generates a random sign (-1 or 1)
*/
nextSign() {
return this.chance(0.5) ? 1 : -1;
}
/**
* Generates a random hexadecimal string
* ⚠️ NOT for cryptographic use - use SecureSeededRNG for secure hex
*/
nextHex(length) {
const chars = "0123456789abcdef";
const result = new Array(length);
for (let i = 0; i < length; i++) {
result[i] = chars[this.nextInt(0, 15)];
}
return result.join("");
}
/**
* Generates a random UUID-like string (NOT a real UUID!)
* ⚠️ NOT for security use - use crypto.randomUUID() for real UUIDs
*/
nextUUID() {
return `${this.nextHex(8)}-${this.nextHex(4)}-${this.nextHex(4)}-${this.nextHex(4)}-${this.nextHex(12)}`;
}
/**
* Creates a new RNG with a random seed derived from this one
*/
fork() {
return new _SeededRNG(this.nextInt(0, 2147483647));
}
};
var SecureSeededRNG = class _SecureSeededRNG {
seed;
initialSeed;
iterations = 0;
// ISAAC state
randRsl;
randCnt;
randA;
randB;
randC;
/**
* Creates a new secure seeded RNG instance
*
* @param seed - Optional seed value. If not provided, uses crypto.getRandomValues()
*
* @example
* ```typescript
* // With a specific seed (reproducible)
* const rng1 = new SecureSeededRNG(42);
*
* // Without seed (cryptographically random each time)
* const rng2 = new SecureSeededRNG();
* ```
*/
constructor(seed) {
this.randRsl = new Array(256);
this.randCnt = 256;
this.randA = 0;
this.randB = 0;
this.randC = 0;
if (seed === void 0) {
let randomSeed = Math.floor(Math.random() * 4294967296);
try {
const array = new Uint32Array(1);
if (typeof globalThis !== "undefined" && "crypto" in globalThis) {
const maybeCrypto = globalThis;
maybeCrypto.crypto?.getRandomValues?.(array);
if (array[0] !== void 0) {
randomSeed = array[0];
}
}
} catch (error) {
console.warn("SecureSeededRNG: crypto.getRandomValues not available, falling back to Math.random:", error);
}
seed = randomSeed;
}
this.initialSeed = seed;
this.seed = seed;
this.isaacSeed(seed);
}
/**
* Initialize ISAAC with a seed
*/
isaacSeed(seed) {
const seedArray = new Array(256);
const GOLDEN_RATIO = 2654435769;
let mix = seed;
for (let i = 0; i < 256; i++) {
mix = (mix ^ mix >>> 16) * GOLDEN_RATIO | 0;
seedArray[i] = mix;
}
this.randA = seed;
this.randB = seed ^ 2654435769;
this.randC = seed ^ 2654435769;
for (let i = 0; i < 256; i++) {
this.randRsl[i] = seedArray[i] ?? 0;
}
this.randCnt = 256;
this.isaac();
}
/**
* ISAAC algorithm - generates 256 random 32-bit values
*/
isaac() {
let i, y;
this.randB = this.randB + (this.randC + 1) | 0 | 0;
this.randC = this.randC + 1 | 0;
for (i = 0; i < 256; i++) {
this.randRsl[i];
switch (i & 3) {
case 0:
this.randA = this.randA ^ this.randA << 13 | 0;
break;
case 1:
this.randA = this.randA ^ this.randA >>> 6 | 0;
break;
case 2:
this.randA = this.randA ^ this.randA << 2 | 0;
break;
case 3:
this.randA = this.randA ^ this.randA >>> 16 | 0;
break;
}
const rslIdx = i + 128 & 255;
const rslVal = this.randRsl[rslIdx] ?? 0;
y = (rslVal + this.randA | 0) + this.randB | 0;
this.randRsl[i] = y;
const idx2 = y >>> 2 & 255;
const rslVal2 = this.randRsl[idx2] ?? 0;
this.randB = rslVal2 + this.randA + this.randB | 0 | 0;
}
}
/**
* Get next 32-bit random value
*/
rand() {
if (this.randCnt === 0) {
this.isaac();
this.randCnt = 256;
}
this.randCnt--;
this.iterations++;
const result = this.randRsl[this.randCnt];
return result ?? 0;
}
/**
* Gets the initial seed value
*/
getInitialSeed() {
return this.initialSeed;
}
/**
* Gets the current state value
*/
getCurrentSeed() {
return this.seed;
}
/**
* Sets the current seed/state
*/
setSeed(seed) {
this.seed = seed;
this.isaacSeed(seed);
}
/**
* Gets statistics about the RNG state
*/
getStats() {
return {
initialSeed: this.initialSeed,
currentSeed: this.seed,
iterations: this.iterations
};
}
/**
* Resets the RNG to its initial state
*/
reset() {
this.seed = this.initialSeed;
this.iterations = 0;
this.isaacSeed(this.initialSeed);
}
/**
* Generates the next random float between 0 (inclusive) and 1 (exclusive)
*/
next() {
return (this.rand() >>> 0) / 4294967296;
}
/**
* Generates a random integer in range [min, max] (inclusive)
* @throws {Error} If min is greater than max
*/
nextInt(min, max) {
if (min > max) {
throw new Error("min must be less than or equal to max");
}
return Math.floor(this.next() * (max - min + 1)) + min;
}
/**
* Generates a random float in range [min, max)
* @throws {Error} If min is greater than max
*/
nextFloat(min, max) {
if (min > max) {
throw new Error("min must be less than max");
}
return this.next() * (max - min) + min;
}
/**
* Returns true with the given probability (0-1)
* @throws {Error} If probability is not between 0 and 1
*/
chance(probability) {
if (probability < 0 || probability > 1) {
throw new Error("probability must be between 0 and 1");
}
return this.next() < probability;
}
/**
* Selects a random element from an array
*/
pick(array) {
if (array.length === 0) return void 0;
return array[this.nextInt(0, array.length - 1)];
}
/**
* Shuffles an array using the Fisher-Yates algorithm
*/
shuffle(array) {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = this.nextInt(0, i);
const temp = result[i];
result[i] = result[j];
result[j] = temp;
}
return result;
}
/**
* Selects a random element based on weights
*/
weightedPick(items) {
if (items.length === 0) return void 0;
const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);
let random = this.next() * totalWeight;
for (const item of items) {
random -= item.weight;
if (random <= 0) {
return item.item;
}
}
return items[items.length - 1]?.item;
}
/**
* Generates a random boolean value
*/
nextBool(probability = 0.5) {
return this.chance(probability);
}
/**
* Generates a random sign (-1 or 1)
*/
nextSign() {
return this.chance(0.5) ? 1 : -1;
}
/**
* Generates a cryptographically secure random hexadecimal string
*
* This IS safe for:
* - Session tokens
* - API keys
* - Reset tokens
* - Any security-sensitive strings
*
* When seeded, always uses ISAAC for deterministic output.
*
* @param length - Number of bytes (each byte becomes 2 hex chars)
*/
nextHex(length) {
const chars = "0123456789abcdef";
const result = new Array(length * 2);
let idx = 0;
for (let i = 0; i < length; i++) {
const byte = this.rand() & 255;
result[idx++] = chars[byte >> 4 & 15];
result[idx++] = chars[byte & 15];
}
return result.join("");
}
/**
* Generates a cryptographically secure random byte array
*
* @param length - Number of random bytes to generate
*/
nextBytes(length) {
const bytes = new Uint8Array(length);
for (let i = 0; i < length; i++) {
bytes[i] = this.rand() & 255;
}
return bytes;
}
/**
* Generates a cryptographically secure random Base64 string
*
* @param length - Number of random bytes before encoding
*/
nextBase64(length) {
const bytes = this.nextBytes(length);
const binary = new Array(bytes.length);
for (let i = 0; i < bytes.length; i++) {
binary[i] = String.fromCharCode(bytes[i] ?? 0);
}
return btoa(binary.join(""));
}
/**
* Generates a random UUID v4 (cryptographically secure)
*
* Uses ISAAC for deterministic UUID generation when seeded.
*/
nextUUID() {
const bytes = new Uint8Array(16);
for (let i = 0; i < 16; i++) {
bytes[i] = this.rand() & 255;
}
const byte6 = bytes[6] ?? 0;
const byte8 = bytes[8] ?? 0;
bytes[6] = byte6 & 15 | 64;
bytes[8] = byte8 & 63 | 128;
const hex = Array.from(bytes).map((b) => (b ?? 0).toString(16).padStart(2, "0")).join("");
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
}
/**
* Creates a new SecureSeededRNG with a random seed derived from this one
*/
fork() {
return new _SecureSeededRNG(this.nextInt(0, 4294967295));
}
};
function createRNG(seed) {
return new SeededRNG(seed ?? void 0);
}
function createSecureRNG(seed) {
return new SecureSeededRNG(seed ?? void 0);
}
function seededInt(seed, min, max) {
const rng = new SeededRNG(seed);
return rng.nextInt(min, max);
}
function seededFloat(seed, min, max) {
const rng = new SeededRNG(seed);
return rng.nextFloat(min, max);
}
function seededShuffle(seed, array) {
const rng = new SeededRNG(seed);
return rng.shuffle(array);
}
function seededPick(seed, array) {
const rng = new SeededRNG(seed);
return rng.pick(array);
}
function seededSecureInt(seed, min, max) {
const rng = new SecureSeededRNG(seed);
return rng.nextInt(min, max);
}
function seededSecureHex(seed, length) {
const rng = new SecureSeededRNG(seed);
return rng.nextHex(length);
}
exports.SecureSeededRNG = SecureSeededRNG;
exports.SeededRNG = SeededRNG;
exports.createRNG = createRNG;
exports.createSecureRNG = createSecureRNG;
exports.default = SeededRNG;
exports.seededFloat = seededFloat;
exports.seededInt = seededInt;
exports.seededPick = seededPick;
exports.seededSecureHex = seededSecureHex;
exports.seededSecureInt = seededSecureInt;
exports.seededShuffle = seededShuffle;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Seeded Random Number Generator\n * \n * ⚠️ **SECURITY WARNING**: The default SeededRNG (LCG) is NOT cryptographically secure!\n * \n * This library provides TWO RNG implementations:\n * \n * 1. **SeededRNG** (LCG) - Fast but NOT secure\n * - Do NOT use for: passwords, keys, tokens, nonces, security\n * - Use for: games, simulations, testing, debugging\n * \n * 2. **SecureSeededRNG** (ISAAC) - Cryptographically Secure\n * - Use for: any security-sensitive operations\n * - Deterministic and reproducible like SeededRNG\n * - Based on ISAAC cipher algorithm\n * \n * For cryptographic randomness without seeding:\n * - Browser: `crypto.getRandomValues()`\n * - Node.js: `crypto.randomBytes()` or `crypto.randomInt()`\n * \n * @module @opensourceframework/seeded-rng\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Options for weighted random selection\n * @since 0.1.0\n */\nexport interface WeightedItem<T> {\n /** The item to potentially select */\n item: T;\n /** The relative weight of this item (higher = more likely) */\n weight: number;\n}\n\n/**\n * Options for creating an RNG instance\n * @since 0.1.0\n */\nexport interface RNGOptions {\n /** The seed value for deterministic randomness */\n seed?: number;\n /** Use cryptographically secure RNG (default: false) */\n secure?: boolean;\n}\n\n/**\n * Statistics about the RNG state\n * @since 0.1.0\n */\nexport interface RNGStats {\n /** The initial seed value */\n initialSeed: number;\n /** The current seed/state value */\n currentSeed: number;\n /** Number of random values generated */\n iterations: number;\n}\n\n// ============================================================================\n// SeededRNG Class (Fast, NOT Cryptographically Secure)\n// ============================================================================\n\n/**\n * Seeded Random Number Generator for deterministic, reproducible randomness.\n * \n * Uses the Linear Congruential Generator (LCG) algorithm for consistent,\n * reproducible random sequences given the same seed.\n * \n * ⚠️ **WARNING**: This is NOT cryptographically secure!\n * Use SecureSeededRNG for security-sensitive applications.\n * \n * @example\n * ```typescript\n * import { SeededRNG } from '@opensourceframework/seeded-rng';\n * \n * // Create with a specific seed for reproducibility\n * const rng = new SeededRNG(12345);\n * \n * console.log(rng.nextInt(1, 100)); // Always same result for seed 12345\n * console.log(rng.next()); // Always same result\n * \n * // Reset to replay the same sequence\n * rng.reset();\n * console.log(rng.nextInt(1, 100)); // Same as first call\n * ```\n * @since 0.1.0\n */\nexport class SeededRNG {\n private seed: number;\n private initialSeed: number;\n private iterations: number = 0;\n\n // LCG parameters (using values from Numerical Recipes)\n private static readonly A = 9301;\n private static readonly C = 49297;\n private static readonly M = 233280;\n\n /**\n * Creates a new seeded RNG instance\n * \n * @param seed - Optional seed value. If not provided, generates a random seed\n * \n * @example\n * ```typescript\n * // With a specific seed (reproducible)\n * const rng1 = new SeededRNG(42);\n * \n * // Without seed (random each time)\n * const rng2 = new SeededRNG();\n * ```\n */\n constructor(seed?: number) {\n this.initialSeed = seed ?? Math.floor(Math.random() * 2147483647);\n this.seed = this.initialSeed;\n }\n\n /**\n * Gets the initial seed value (useful for serialization/replay)\n */\n getInitialSeed(): number {\n return this.initialSeed;\n }\n\n /**\n * Gets the current seed/state value\n */\n getCurrentSeed(): number {\n return this.seed;\n }\n\n /**\n * Sets the current seed/state\n */\n setSeed(seed: number): void {\n this.seed = seed;\n }\n\n /**\n * Gets statistics about the RNG state\n */\n getStats(): RNGStats {\n return {\n initialSeed: this.initialSeed,\n currentSeed: this.seed,\n iterations: this.iterations,\n };\n }\n\n /**\n * Resets the RNG to its initial state\n */\n reset(): void {\n this.seed = this.initialSeed;\n this.iterations = 0;\n }\n\n /**\n * Generates the next random float between 0 (inclusive) and 1 (exclusive)\n * Uses LCG algorithm: seed = (seed * a + c) % m\n */\n next(): number {\n this.seed = (this.seed * SeededRNG.A + SeededRNG.C) % SeededRNG.M;\n this.iterations++;\n return this.seed / SeededRNG.M;\n }\n\n /**\n * Generates a random integer in range [min, max] (inclusive)\n * @throws {Error} If min is greater than max\n */\n nextInt(min: number, max: number): number {\n if (min > max) {\n throw new Error('min must be less than or equal to max');\n }\n return Math.floor(this.next() * (max - min + 1)) + min;\n }\n\n /**\n * Generates a random float in range [min, max)\n * @throws {Error} If min is greater than max\n */\n nextFloat(min: number, max: number): number {\n if (min > max) {\n throw new Error('min must be less than max');\n }\n return this.next() * (max - min) + min;\n }\n\n /**\n * Returns true with the given probability (0-1)\n */\n chance(probability: number): boolean {\n return this.next() < probability;\n }\n\n /**\n * Selects a random element from an array\n */\n pick<T>(array: T[]): T | undefined {\n if (array.length === 0) return undefined;\n return array[this.nextInt(0, array.length - 1)];\n }\n\n /**\n * Shuffles an array using the Fisher-Yates algorithm\n */\n shuffle<T>(array: T[]): T[] {\n const result = [...array];\n for (let i = result.length - 1; i > 0; i--) {\n const j = this.nextInt(0, i);\n const temp = result[i];\n result[i] = result[j] as T;\n result[j] = temp as T;\n }\n return result;\n }\n\n /**\n * Selects a random element based on weights\n */\n weightedPick<T>(items: WeightedItem<T>[]): T | undefined {\n if (items.length === 0) return undefined;\n\n const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);\n let random = this.next() * totalWeight;\n\n for (const item of items) {\n random -= item.weight;\n if (random <= 0) {\n return item.item;\n }\n }\n\n return items[items.length - 1]?.item;\n }\n\n /**\n * Generates a random boolean value\n */\n nextBool(probability: number = 0.5): boolean {\n return this.chance(probability);\n }\n\n /**\n * Generates a random sign (-1 or 1)\n */\n nextSign(): -1 | 1 {\n return this.chance(0.5) ? 1 : -1;\n }\n\n /**\n * Generates a random hexadecimal string\n * ⚠️ NOT for cryptographic use - use SecureSeededRNG for secure hex\n */\n nextHex(length: number): string {\n const chars = '0123456789abcdef';\n const result = new Array(length);\n for (let i = 0; i < length; i++) {\n result[i] = chars[this.nextInt(0, 15)];\n }\n return result.join('');\n }\n\n /**\n * Generates a random UUID-like string (NOT a real UUID!)\n * ⚠️ NOT for security use - use crypto.randomUUID() for real UUIDs\n */\n nextUUID(): string {\n return `${this.nextHex(8)}-${this.nextHex(4)}-${this.nextHex(4)}-${this.nextHex(4)}-${this.nextHex(12)}`;\n }\n\n /**\n * Creates a new RNG with a random seed derived from this one\n */\n fork(): SeededRNG {\n return new SeededRNG(this.nextInt(0, 2147483647));\n }\n}\n\n// ============================================================================\n// SecureSeededRNG Class (Cryptographically Secure - ISAAC)\n// ============================================================================\n\n/**\n * Cryptographically Secure Seeded Random Number Generator\n * \n * Uses the ISAAC (Indirection, Shift, Accumulate, Add, and Count) cipher\n * algorithm to generate cryptographically secure pseudo-random numbers.\n * \n * This is suitable for:\n * - Password generation\n * - Cryptographic keys\n * - Session tokens\n * - Nonce generation\n * - Any security-sensitive operations\n * \n * Like SeededRNG, this is deterministic - the same seed produces the same sequence.\n * \n * @example\n * ```typescript\n * import { SecureSeededRNG } from '@opensourceframework/seeded-rng';\n * \n * // Create with a specific seed for reproducibility\n * const rng = new SecureSeededRNG(12345);\n * \n * console.log(rng.nextInt(1, 100)); // Always same result for seed 12345\n * console.log(rng.nextHex(32)); // Always same secure hex for seed 12345\n * \n * // Reset to replay the same sequence\n * rng.reset();\n * console.log(rng.nextInt(1, 100)); // Same as first call\n * ```\n * \n * @example\n * ```typescript\n * // Generate a secure random password\n * const rng = new SecureSeededRNG();\n * const password = rng.nextHex(32); // 32 bytes of secure randomness\n * ```\n * @since 0.1.0\n */\nexport class SecureSeededRNG {\n private seed: number;\n private initialSeed: number;\n private iterations: number = 0;\n \n // ISAAC state\n private randRsl: number[];\n private randCnt: number;\n private randA: number;\n private randB: number;\n private randC: number;\n\n /**\n * Creates a new secure seeded RNG instance\n * \n * @param seed - Optional seed value. If not provided, uses crypto.getRandomValues()\n * \n * @example\n * ```typescript\n * // With a specific seed (reproducible)\n * const rng1 = new SecureSeededRNG(42);\n * \n * // Without seed (cryptographically random each time)\n * const rng2 = new SecureSeededRNG();\n * ```\n */\n constructor(seed?: number) {\n // Initialize arrays\n this.randRsl = new Array(256);\n this.randCnt = 256;\n this.randA = 0;\n this.randB = 0;\n this.randC = 0;\n \n // Use crypto API if available for initial random seed\n if (seed === undefined) {\n let randomSeed = Math.floor(Math.random() * 4294967296);\n \n try {\n // Try to use crypto.getRandomValues\n const array = new Uint32Array(1);\n // Use type-safe check for crypto.getRandomValues\n if (typeof globalThis !== 'undefined' && 'crypto' in globalThis) {\n const maybeCrypto = globalThis as { crypto?: { getRandomValues?: (arr: Uint32Array) => Uint32Array } };\n maybeCrypto.crypto?.getRandomValues?.(array);\n if (array[0] !== undefined) {\n randomSeed = array[0];\n }\n }\n } catch (error) {\n console.warn('SecureSeededRNG: crypto.getRandomValues not available, falling back to Math.random:', error);\n }\n \n seed = randomSeed;\n }\n \n this.initialSeed = seed;\n this.seed = seed;\n this.isaacSeed(seed);\n }\n\n /**\n * Initialize ISAAC with a seed\n */\n private isaacSeed(seed: number): void {\n // Generate 256 32-bit values from the seed using a mixing function\n const seedArray: number[] = new Array(256);\n \n // Simple seed expansion - mix the seed with golden ratio\n const GOLDEN_RATIO = 0x9e3779b9;\n let mix = seed;\n \n for (let i = 0; i < 256; i++) {\n mix = (mix ^ (mix >>> 16)) * GOLDEN_RATIO | 0;\n seedArray[i] = mix;\n }\n \n // Initialize randA, randB, randC with values derived from seed\n this.randA = seed;\n this.randB = seed ^ 0x9e3779b9;\n this.randC = seed ^ 0x9e3779b9;\n \n // Initialize randRsl with seed array\n for (let i = 0; i < 256; i++) {\n this.randRsl[i] = seedArray[i] ?? 0;\n }\n \n // Initialize randCnt\n this.randCnt = 256;\n \n // First round of ISAAC - warm up\n this.isaac();\n }\n\n /**\n * ISAAC algorithm - generates 256 random 32-bit values\n */\n private isaac(): void {\n let i, _x, y;\n \n this.randB = (this.randB + (this.randC + 1) | 0) | 0;\n this.randC = (this.randC + 1) | 0;\n \n for (i = 0; i < 256; i++) {\n _x = this.randRsl[i];\n \n switch (i & 3) {\n case 0:\n this.randA = (this.randA ^ (this.randA << 13)) | 0;\n break;\n case 1:\n this.randA = (this.randA ^ (this.randA >>> 6)) | 0;\n break;\n case 2:\n this.randA = (this.randA ^ (this.randA << 2)) | 0;\n break;\n case 3:\n this.randA = (this.randA ^ (this.randA >>> 16)) | 0;\n break;\n }\n \n const rslIdx = (i + 128) & 0xff;\n const rslVal = this.randRsl[rslIdx] ?? 0;\n y = ((rslVal + this.randA) | 0) + this.randB | 0;\n \n this.randRsl[i] = y;\n \n const idx2 = (y >>> 2) & 0xff;\n const rslVal2 = this.randRsl[idx2] ?? 0;\n this.randB = ((rslVal2 + this.randA + this.randB) | 0) | 0;\n }\n }\n\n /**\n * Get next 32-bit random value\n */\n private rand(): number {\n if (this.randCnt === 0) {\n this.isaac();\n this.randCnt = 256;\n }\n \n this.randCnt--;\n this.iterations++;\n \n const result = this.randRsl[this.randCnt];\n return result ?? 0;\n }\n\n /**\n * Gets the initial seed value\n */\n getInitialSeed(): number {\n return this.initialSeed;\n }\n\n /**\n * Gets the current state value\n */\n getCurrentSeed(): number {\n return this.seed;\n }\n\n /**\n * Sets the current seed/state\n */\n setSeed(seed: number): void {\n this.seed = seed;\n this.isaacSeed(seed);\n }\n\n /**\n * Gets statistics about the RNG state\n */\n getStats(): RNGStats {\n return {\n initialSeed: this.initialSeed,\n currentSeed: this.seed,\n iterations: this.iterations,\n };\n }\n\n /**\n * Resets the RNG to its initial state\n */\n reset(): void {\n this.seed = this.initialSeed;\n this.iterations = 0;\n this.isaacSeed(this.initialSeed);\n }\n\n /**\n * Generates the next random float between 0 (inclusive) and 1 (exclusive)\n */\n next(): number {\n // Use >>> 0 to convert signed 32-bit int to unsigned before division\n return (this.rand() >>> 0) / 4294967296;\n }\n\n /**\n * Generates a random integer in range [min, max] (inclusive)\n * @throws {Error} If min is greater than max\n */\n nextInt(min: number, max: number): number {\n if (min > max) {\n throw new Error('min must be less than or equal to max');\n }\n return Math.floor(this.next() * (max - min + 1)) + min;\n }\n\n /**\n * Generates a random float in range [min, max)\n * @throws {Error} If min is greater than max\n */\n nextFloat(min: number, max: number): number {\n if (min > max) {\n throw new Error('min must be less than max');\n }\n return this.next() * (max - min) + min;\n }\n\n /**\n * Returns true with the given probability (0-1)\n * @throws {Error} If probability is not between 0 and 1\n */\n chance(probability: number): boolean {\n if (probability < 0 || probability > 1) {\n throw new Error('probability must be between 0 and 1');\n }\n return this.next() < probability;\n }\n\n /**\n * Selects a random element from an array\n */\n pick<T>(array: T[]): T | undefined {\n if (array.length === 0) return undefined;\n return array[this.nextInt(0, array.length - 1)];\n }\n\n /**\n * Shuffles an array using the Fisher-Yates algorithm\n */\n shuffle<T>(array: T[]): T[] {\n const result = [...array];\n for (let i = result.length - 1; i > 0; i--) {\n const j = this.nextInt(0, i);\n const temp = result[i];\n result[i] = result[j] as T;\n result[j] = temp as T;\n }\n return result;\n }\n\n /**\n * Selects a random element based on weights\n */\n weightedPick<T>(items: WeightedItem<T>[]): T | undefined {\n if (items.length === 0) return undefined;\n\n const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);\n let random = this.next() * totalWeight;\n\n for (const item of items) {\n random -= item.weight;\n if (random <= 0) {\n return item.item;\n }\n }\n\n return items[items.length - 1]?.item;\n }\n\n /**\n * Generates a random boolean value\n */\n nextBool(probability: number = 0.5): boolean {\n return this.chance(probability);\n }\n\n /**\n * Generates a random sign (-1 or 1)\n */\n nextSign(): -1 | 1 {\n return this.chance(0.5) ? 1 : -1;\n }\n\n /**\n * Generates a cryptographically secure random hexadecimal string\n * \n * This IS safe for:\n * - Session tokens\n * - API keys\n * - Reset tokens\n * - Any security-sensitive strings\n * \n * When seeded, always uses ISAAC for deterministic output.\n * \n * @param length - Number of bytes (each byte becomes 2 hex chars)\n */\n nextHex(length: number): string {\n const chars = '0123456789abcdef';\n const result = new Array(length * 2);\n \n // Always use ISAAC for deterministic behavior when seeded\n // crypto.getRandomValues would break determinism\n let idx = 0;\n for (let i = 0; i < length; i++) {\n const byte = this.rand() & 0xff;\n result[idx++] = chars[(byte >> 4) & 0x0f];\n result[idx++] = chars[byte & 0x0f];\n }\n return result.join('');\n }\n\n /**\n * Generates a cryptographically secure random byte array\n * \n * @param length - Number of random bytes to generate\n */\n nextBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n \n // Always use ISAAC for deterministic behavior when seeded\n // crypto.getRandomValues would break determinism\n for (let i = 0; i < length; i++) {\n bytes[i] = this.rand() & 0xff;\n }\n \n return bytes;\n }\n\n /**\n * Generates a cryptographically secure random Base64 string\n * \n * @param length - Number of random bytes before encoding\n */\n nextBase64(length: number): string {\n const bytes = this.nextBytes(length);\n const binary = new Array(bytes.length);\n for (let i = 0; i < bytes.length; i++) {\n binary[i] = String.fromCharCode(bytes[i] ?? 0);\n }\n return btoa(binary.join(''));\n }\n\n /**\n * Generates a random UUID v4 (cryptographically secure)\n * \n * Uses ISAAC for deterministic UUID generation when seeded.\n */\n nextUUID(): string {\n // Use ISAAC for deterministic UUID generation when seeded\n const bytes = new Uint8Array(16);\n for (let i = 0; i < 16; i++) {\n bytes[i] = this.rand() & 0xff;\n }\n \n // Set version (4) and variant (RFC 4122)\n const byte6 = bytes[6] ?? 0;\n const byte8 = bytes[8] ?? 0;\n bytes[6] = (byte6 & 0x0f) | 0x40;\n bytes[8] = (byte8 & 0x3f) | 0x80;\n \n const hex = Array.from(bytes).map(b => (b ?? 0).toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`;\n }\n\n /**\n * Creates a new SecureSeededRNG with a random seed derived from this one\n */\n fork(): SecureSeededRNG {\n return new SecureSeededRNG(this.nextInt(0, 4294967295));\n }\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Creates a new SeededRNG instance (fast, NOT cryptographically secure)\n * \n * This is a convenience factory function that creates a new SeededRNG instance.\n * The SeededRNG uses a Linear Congruential Generator (LCG) algorithm which is\n * fast but NOT suitable for security-sensitive operations.\n * \n * @param seed - Optional seed value. If not provided, a random seed will be generated.\n * Pass `null` to explicitly indicate no seed is provided.\n * @returns A new SeededRNG instance initialized with the provided or generated seed\n * \n * @example\n * ```typescript\n * // With a specific seed (reproducible sequences)\n * const rng = createRNG(42);\n * console.log(rng.nextInt(1, 100)); // Always returns the same value\n * \n * // Without seed (random each time)\n * const rng2 = createRNG();\n * ```\n * \n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random|Math.random}\n * @group Seeded RNG\n * @since 0.1.0\n */\nexport function createRNG(seed?: number | null): SeededRNG {\n return new SeededRNG(seed ?? undefined);\n}\n\n/**\n * Creates a new SecureSeededRNG instance (cryptographically secure)\n * \n * This is a convenience factory function that creates a new SecureSeededRNG instance.\n * The SecureSeededRNG uses the ISAAC cipher algorithm which is cryptographically\n * secure and suitable for security-sensitive operations like password generation,\n * token creation, and cryptographic key derivation.\n * \n * @param seed - Optional seed value for deterministic sequences.\n * If not provided, a cryptographically random seed will be generated\n * using `crypto.getRandomValues()` where available.\n * Pass `null` to explicitly indicate no seed is provided.\n * @returns A new SecureSeededRNG instance initialized with the provided or generated seed\n * \n * @example\n * ```typescript\n * // With a specific seed (reproducible sequences)\n * const rng = createSecureRNG(42);\n * console.log(rng.nextHex(16)); // Always returns the same value\n * \n * // Without seed (cryptographically random each time)\n * const rng2 = createSecureRNG();\n * const password = rng2.nextHex(32); // 32-byte secure password\n * ```\n * \n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues|crypto.getRandomValues}\n * @group Secure RNG\n * @since 0.1.0\n */\nexport function createSecureRNG(seed?: number | null): SecureSeededRNG {\n return new SecureSeededRNG(seed ?? undefined);\n}\n\n/**\n * Generates a single random integer with a seed (one-shot, NOT secure)\n * \n * Creates a temporary SeededRNG instance, generates a single random integer\n * in the specified range [min, max], and returns the result.\n * \n * ⚠️ This is NOT cryptographically secure. Use for games, testing, or\n * non-security-related randomness only.\n * \n * @param seed - The seed value for deterministic randomness\n * @param min - Minimum value (inclusive)\n * @param max - Maximum value (inclusive)\n * @returns A random integer between min and max (inclusive)\n * \n * @example\n * ```typescript\n * // Always returns the same value for the same seed\n * console.log(seededInt(12345, 1, 100)); // Always returns 38 (for example)\n * ```\n * \n * @see {@link SeededRNG.nextInt}\n * @since 0.1.0\n */\nexport function seededInt(seed: number, min: number, max: number): number {\n const rng = new SeededRNG(seed);\n return rng.nextInt(min, max);\n}\n\n/**\n * Generates a single random float with a seed (one-shot, NOT secure)\n * \n * Creates a temporary SeededRNG instance, generates a single random float\n * in the specified range [min, max), and returns the result.\n * \n * ⚠️ This is NOT cryptographically secure. Use for games, testing, or\n * non-security-related randomness only.\n * \n * @param seed - The seed value for deterministic randomness\n * @param min - Minimum value (inclusive)\n * @param max - Maximum value (exclusive)\n * @returns A random float between min (inclusive) and max (exclusive)\n * \n * @example\n * ```typescript\n * // Always returns the same value for the same seed\n * console.log(seededFloat(12345, 0.0, 1.0)); // Always returns 0.83... (for example)\n * ```\n * \n * @see {@link SeededRNG.nextFloat}\n * @since 0.1.0\n */\nexport function seededFloat(seed: number, min: number, max: number): number {\n const rng = new SeededRNG(seed);\n return rng.nextFloat(min, max);\n}\n\n/**\n * Shuffles an array with a seed (one-shot, NOT secure)\n * \n * Creates a temporary SeededRNG instance, shuffles the array using the\n * Fisher-Yates algorithm with the seeded random number generator, and\n * returns a new shuffled array.\n * \n * ⚠️ This is NOT cryptographically secure. Use for games, testing, or\n * non-security-related randomness only.\n * \n * @param seed - The seed value for deterministic shuffling\n * @param array - The array to shuffle\n * @returns A new array with elements in random order (deterministic based on seed)\n * \n * @example\n * ```typescript\n * // Always produces the same shuffle for the same seed\n * const result = seededShuffle(42, ['a', 'b', 'c', 'd']);\n * // Result is always: ['c', 'a', 'd', 'b'] (for example)\n * ```\n * \n * @see {@link SeededRNG.shuffle}\n * @since 0.1.0\n */\nexport function seededShuffle<T>(seed: number, array: T[]): T[] {\n const rng = new SeededRNG(seed);\n return rng.shuffle(array);\n}\n\n/**\n * Picks a random element with a seed (one-shot, NOT secure)\n * \n * Creates a temporary SeededRNG instance and selects a random element\n * from the provided array.\n * \n * ⚠️ This is NOT cryptographically secure. Use for games, testing, or\n * non-security-related randomness only.\n * \n * @param seed - The seed value for deterministic selection\n * @param array - The array to pick from\n * @returns A randomly selected element from the array, or undefined if empty\n * \n * @example\n * ```typescript\n * // Always picks the same element for the same seed\n * const item = seededPick(42, ['apple', 'banana', 'cherry']);\n * // Always returns 'banana' (for example)\n * \n * // Returns undefined for empty arrays\n * const empty = seededPick(1, []); // Returns undefined\n * ```\n * \n * @see {@link SeededRNG.pick}\n * @since 0.1.0\n */\nexport function seededPick<T>(seed: number, array: T[]): T | undefined {\n const rng = new SeededRNG(seed);\n return rng.pick(array);\n}\n\n/**\n * Generates a single cryptographically secure random integer with a seed\n * \n * Creates a temporary SecureSeededRNG instance and generates a single\n * random integer in the specified range [min, max].\n * \n * This IS cryptographically secure and suitable for security-sensitive\n * operations like generating random IDs, tokens, or any value that\n * should not be predictable.\n * \n * @param seed - The seed value for deterministic (but still secure) sequences\n * @param min - Minimum value (inclusive)\n * @param max - Maximum value (inclusive)\n * @returns A cryptographically secure random integer between min and max (inclusive)\n * \n * @example\n * ```typescript\n * // Generates a secure random number (still deterministic with same seed)\n * const num = seededSecureInt(42, 1, 1000000);\n * ```\n * \n * @see {@link SecureSeededRNG.nextInt}\n * @since 0.1.0\n */\nexport function seededSecureInt(seed: number, min: number, max: number): number {\n const rng = new SecureSeededRNG(seed);\n return rng.nextInt(min, max);\n}\n\n/**\n * Generates a cryptographically secure random hex string (seeded)\n * \n * Creates a temporary SecureSeededRNG instance and generates a\n * cryptographically secure hexadecimal string.\n * \n * This IS safe for:\n * - Session tokens\n * - API keys\n * - Password reset tokens\n * - Any security-sensitive strings\n * \n * @param seed - The seed value for deterministic (but still secure) sequences\n * @param length - Number of bytes (each byte becomes 2 hex characters)\n * @returns A cryptographically secure hexadecimal string\n * \n * @example\n * ```typescript\n * // Generate a 32-byte (64 character) secure hex string\n * const token = seededSecureHex(42, 32);\n * // Returns: 'a1b2c3d4e5f6...'\n * \n * // Generate a 16-byte API key\n * const apiKey = seededSecureHex(Date.now(), 16);\n * ```\n * \n * @see {@link SecureSeededRNG.nextHex}\n * @since 0.1.0\n */\nexport function seededSecureHex(seed: number, length: number): string {\n const rng = new SecureSeededRNG(seed);\n return rng.nextHex(length);\n}\n\nexport { SeededRNG as default };\n"]}
/**
* Seeded Random Number Generator
*
* ⚠️ **SECURITY WARNING**: The default SeededRNG (LCG) is NOT cryptographically secure!
*
* This library provides TWO RNG implementations:
*
* 1. **SeededRNG** (LCG) - Fast but NOT secure
* - Do NOT use for: passwords, keys, tokens, nonces, security
* - Use for: games, simulations, testing, debugging
*
* 2. **SecureSeededRNG** (ISAAC) - Cryptographically Secure
* - Use for: any security-sensitive operations
* - Deterministic and reproducible like SeededRNG
* - Based on ISAAC cipher algorithm
*
* For cryptographic randomness without seeding:
* - Browser: `crypto.getRandomValues()`
* - Node.js: `crypto.randomBytes()` or `crypto.randomInt()`
*
* @module @opensourceframework/seeded-rng
*/
/**
* Options for weighted random selection
* @since 0.1.0
*/
interface WeightedItem<T> {
/** The item to potentially select */
item: T;
/** The relative weight of this item (higher = more likely) */
weight: number;
}
/**
* Options for creating an RNG instance
* @since 0.1.0
*/
interface RNGOptions {
/** The seed value for deterministic randomness */
seed?: number;
/** Use cryptographically secure RNG (default: false) */
secure?: boolean;
}
/**
* Statistics about the RNG state
* @since 0.1.0
*/
interface RNGStats {
/** The initial seed value */
initialSeed: number;
/** The current seed/state value */
currentSeed: number;
/** Number of random values generated */
iterations: number;
}
/**
* Seeded Random Number Generator for deterministic, reproducible randomness.
*
* Uses the Linear Congruential Generator (LCG) algorithm for consistent,
* reproducible random sequences given the same seed.
*
* ⚠️ **WARNING**: This is NOT cryptographically secure!
* Use SecureSeededRNG for security-sensitive applications.
*
* @example
* ```typescript
* import { SeededRNG } from '@opensourceframework/seeded-rng';
*
* // Create with a specific seed for reproducibility
* const rng = new SeededRNG(12345);
*
* console.log(rng.nextInt(1, 100)); // Always same result for seed 12345
* console.log(rng.next()); // Always same result
*
* // Reset to replay the same sequence
* rng.reset();
* console.log(rng.nextInt(1, 100)); // Same as first call
* ```
* @since 0.1.0
*/
declare class SeededRNG {
private seed;
private initialSeed;
private iterations;
private static readonly A;
private static readonly C;
private static readonly M;
/**
* Creates a new seeded RNG instance
*
* @param seed - Optional seed value. If not provided, generates a random seed
*
* @example
* ```typescript
* // With a specific seed (reproducible)
* const rng1 = new SeededRNG(42);
*
* // Without seed (random each time)
* const rng2 = new SeededRNG();
* ```
*/
constructor(seed?: number);
/**
* Gets the initial seed value (useful for serialization/replay)
*/
getInitialSeed(): number;
/**
* Gets the current seed/state value
*/
getCurrentSeed(): number;
/**
* Sets the current seed/state
*/
setSeed(seed: number): void;
/**
* Gets statistics about the RNG state
*/
getStats(): RNGStats;
/**
* Resets the RNG to its initial state
*/
reset(): void;
/**
* Generates the next random float between 0 (inclusive) and 1 (exclusive)
* Uses LCG algorithm: seed = (seed * a + c) % m
*/
next(): number;
/**
* Generates a random integer in range [min, max] (inclusive)
* @throws {Error} If min is greater than max
*/
nextInt(min: number, max: number): number;
/**
* Generates a random float in range [min, max)
* @throws {Error} If min is greater than max
*/
nextFloat(min: number, max: number): number;
/**
* Returns true with the given probability (0-1)
*/
chance(probability: number): boolean;
/**
* Selects a random element from an array
*/
pick<T>(array: T[]): T | undefined;
/**
* Shuffles an array using the Fisher-Yates algorithm
*/
shuffle<T>(array: T[]): T[];
/**
* Selects a random element based on weights
*/
weightedPick<T>(items: WeightedItem<T>[]): T | undefined;
/**
* Generates a random boolean value
*/
nextBool(probability?: number): boolean;
/**
* Generates a random sign (-1 or 1)
*/
nextSign(): -1 | 1;
/**
* Generates a random hexadecimal string
* ⚠️ NOT for cryptographic use - use SecureSeededRNG for secure hex
*/
nextHex(length: number): string;
/**
* Generates a random UUID-like string (NOT a real UUID!)
* ⚠️ NOT for security use - use crypto.randomUUID() for real UUIDs
*/
nextUUID(): string;
/**
* Creates a new RNG with a random seed derived from this one
*/
fork(): SeededRNG;
}
/**
* Cryptographically Secure Seeded Random Number Generator
*
* Uses the ISAAC (Indirection, Shift, Accumulate, Add, and Count) cipher
* algorithm to generate cryptographically secure pseudo-random numbers.
*
* This is suitable for:
* - Password generation
* - Cryptographic keys
* - Session tokens
* - Nonce generation
* - Any security-sensitive operations
*
* Like SeededRNG, this is deterministic - the same seed produces the same sequence.
*
* @example
* ```typescript
* import { SecureSeededRNG } from '@opensourceframework/seeded-rng';
*
* // Create with a specific seed for reproducibility
* const rng = new SecureSeededRNG(12345);
*
* console.log(rng.nextInt(1, 100)); // Always same result for seed 12345
* console.log(rng.nextHex(32)); // Always same secure hex for seed 12345
*
* // Reset to replay the same sequence
* rng.reset();
* console.log(rng.nextInt(1, 100)); // Same as first call
* ```
*
* @example
* ```typescript
* // Generate a secure random password
* const rng = new SecureSeededRNG();
* const password = rng.nextHex(32); // 32 bytes of secure randomness
* ```
* @since 0.1.0
*/
declare class SecureSeededRNG {
private seed;
private initialSeed;
private iterations;
private randRsl;
private randCnt;
private randA;
private randB;
private randC;
/**
* Creates a new secure seeded RNG instance
*
* @param seed - Optional seed value. If not provided, uses crypto.getRandomValues()
*
* @example
* ```typescript
* // With a specific seed (reproducible)
* const rng1 = new SecureSeededRNG(42);
*
* // Without seed (cryptographically random each time)
* const rng2 = new SecureSeededRNG();
* ```
*/
constructor(seed?: number);
/**
* Initialize ISAAC with a seed
*/
private isaacSeed;
/**
* ISAAC algorithm - generates 256 random 32-bit values
*/
private isaac;
/**
* Get next 32-bit random value
*/
private rand;
/**
* Gets the initial seed value
*/
getInitialSeed(): number;
/**
* Gets the current state value
*/
getCurrentSeed(): number;
/**
* Sets the current seed/state
*/
setSeed(seed: number): void;
/**
* Gets statistics about the RNG state
*/
getStats(): RNGStats;
/**
* Resets the RNG to its initial state
*/
reset(): void;
/**
* Generates the next random float between 0 (inclusive) and 1 (exclusive)
*/
next(): number;
/**
* Generates a random integer in range [min, max] (inclusive)
* @throws {Error} If min is greater than max
*/
nextInt(min: number, max: number): number;
/**
* Generates a random float in range [min, max)
* @throws {Error} If min is greater than max
*/
nextFloat(min: number, max: number): number;
/**
* Returns true with the given probability (0-1)
* @throws {Error} If probability is not between 0 and 1
*/
chance(probability: number): boolean;
/**
* Selects a random element from an array
*/
pick<T>(array: T[]): T | undefined;
/**
* Shuffles an array using the Fisher-Yates algorithm
*/
shuffle<T>(array: T[]): T[];
/**
* Selects a random element based on weights
*/
weightedPick<T>(items: WeightedItem<T>[]): T | undefined;
/**
* Generates a random boolean value
*/
nextBool(probability?: number): boolean;
/**
* Generates a random sign (-1 or 1)
*/
nextSign(): -1 | 1;
/**
* Generates a cryptographically secure random hexadecimal string
*
* This IS safe for:
* - Session tokens
* - API keys
* - Reset tokens
* - Any security-sensitive strings
*
* When seeded, always uses ISAAC for deterministic output.
*
* @param length - Number of bytes (each byte becomes 2 hex chars)
*/
nextHex(length: number): string;
/**
* Generates a cryptographically secure random byte array
*
* @param length - Number of random bytes to generate
*/
nextBytes(length: number): Uint8Array;
/**
* Generates a cryptographically secure random Base64 string
*
* @param length - Number of random bytes before encoding
*/
nextBase64(length: number): string;
/**
* Generates a random UUID v4 (cryptographically secure)
*
* Uses ISAAC for deterministic UUID generation when seeded.
*/
nextUUID(): string;
/**
* Creates a new SecureSeededRNG with a random seed derived from this one
*/
fork(): SecureSeededRNG;
}
/**
* Creates a new SeededRNG instance (fast, NOT cryptographically secure)
*
* This is a convenience factory function that creates a new SeededRNG instance.
* The SeededRNG uses a Linear Congruential Generator (LCG) algorithm which is
* fast but NOT suitable for security-sensitive operations.
*
* @param seed - Optional seed value. If not provided, a random seed will be generated.
* Pass `null` to explicitly indicate no seed is provided.
* @returns A new SeededRNG instance initialized with the provided or generated seed
*
* @example
* ```typescript
* // With a specific seed (reproducible sequences)
* const rng = createRNG(42);
* console.log(rng.nextInt(1, 100)); // Always returns the same value
*
* // Without seed (random each time)
* const rng2 = createRNG();
* ```
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random|Math.random}
* @group Seeded RNG
* @since 0.1.0
*/
declare function createRNG(seed?: number | null): SeededRNG;
/**
* Creates a new SecureSeededRNG instance (cryptographically secure)
*
* This is a convenience factory function that creates a new SecureSeededRNG instance.
* The SecureSeededRNG uses the ISAAC cipher algorithm which is cryptographically
* secure and suitable for security-sensitive operations like password generation,
* token creation, and cryptographic key derivation.
*
* @param seed - Optional seed value for deterministic sequences.
* If not provided, a cryptographically random seed will be generated
* using `crypto.getRandomValues()` where available.
* Pass `null` to explicitly indicate no seed is provided.
* @returns A new SecureSeededRNG instance initialized with the provided or generated seed
*
* @example
* ```typescript
* // With a specific seed (reproducible sequences)
* const rng = createSecureRNG(42);
* console.log(rng.nextHex(16)); // Always returns the same value
*
* // Without seed (cryptographically random each time)
* const rng2 = createSecureRNG();
* const password = rng2.nextHex(32); // 32-byte secure password
* ```
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues|crypto.getRandomValues}
* @group Secure RNG
* @since 0.1.0
*/
declare function createSecureRNG(seed?: number | null): SecureSeededRNG;
/**
* Generates a single random integer with a seed (one-shot, NOT secure)
*
* Creates a temporary SeededRNG instance, generates a single random integer
* in the specified range [min, max], and returns the result.
*
* ⚠️ This is NOT cryptographically secure. Use for games, testing, or
* non-security-related randomness only.
*
* @param seed - The seed value for deterministic randomness
* @param min - Minimum value (inclusive)
* @param max - Maximum value (inclusive)
* @returns A random integer between min and max (inclusive)
*
* @example
* ```typescript
* // Always returns the same value for the same seed
* console.log(seededInt(12345, 1, 100)); // Always returns 38 (for example)
* ```
*
* @see {@link SeededRNG.nextInt}
* @since 0.1.0
*/
declare function seededInt(seed: number, min: number, max: number): number;
/**
* Generates a single random float with a seed (one-shot, NOT secure)
*
* Creates a temporary SeededRNG instance, generates a single random float
* in the specified range [min, max), and returns the result.
*
* ⚠️ This is NOT cryptographically secure. Use for games, testing, or
* non-security-related randomness only.
*
* @param seed - The seed value for deterministic randomness
* @param min - Minimum value (inclusive)
* @param max - Maximum value (exclusive)
* @returns A random float between min (inclusive) and max (exclusive)
*
* @example
* ```typescript
* // Always returns the same value for the same seed
* console.log(seededFloat(12345, 0.0, 1.0)); // Always returns 0.83... (for example)
* ```
*
* @see {@link SeededRNG.nextFloat}
* @since 0.1.0
*/
declare function seededFloat(seed: number, min: number, max: number): number;
/**
* Shuffles an array with a seed (one-shot, NOT secure)
*
* Creates a temporary SeededRNG instance, shuffles the array using the
* Fisher-Yates algorithm with the seeded random number generator, and
* returns a new shuffled array.
*
* ⚠️ This is NOT cryptographically secure. Use for games, testing, or
* non-security-related randomness only.
*
* @param seed - The seed value for deterministic shuffling
* @param array - The array to shuffle
* @returns A new array with elements in random order (deterministic based on seed)
*
* @example
* ```typescript
* // Always produces the same shuffle for the same seed
* const result = seededShuffle(42, ['a', 'b', 'c', 'd']);
* // Result is always: ['c', 'a', 'd', 'b'] (for example)
* ```
*
* @see {@link SeededRNG.shuffle}
* @since 0.1.0
*/
declare function seededShuffle<T>(seed: number, array: T[]): T[];
/**
* Picks a random element with a seed (one-shot, NOT secure)
*
* Creates a temporary SeededRNG instance and selects a random element
* from the provided array.
*
* ⚠️ This is NOT cryptographically secure. Use for games, testing, or
* non-security-related randomness only.
*
* @param seed - The seed value for deterministic selection
* @param array - The array to pick from
* @returns A randomly selected element from the array, or undefined if empty
*
* @example
* ```typescript
* // Always picks the same element for the same seed
* const item = seededPick(42, ['apple', 'banana', 'cherry']);
* // Always returns 'banana' (for example)
*
* // Returns undefined for empty arrays
* const empty = seededPick(1, []); // Returns undefined
* ```
*
* @see {@link SeededRNG.pick}
* @since 0.1.0
*/
declare function seededPick<T>(seed: number, array: T[]): T | undefined;
/**
* Generates a single cryptographically secure random integer with a seed
*
* Creates a temporary SecureSeededRNG instance and generates a single
* random integer in the specified range [min, max].
*
* This IS cryptographically secure and suitable for security-sensitive
* operations like generating random IDs, tokens, or any value that
* should not be predictable.
*
* @param seed - The seed value for deterministic (but still secure) sequences
* @param min - Minimum value (inclusive)
* @param max - Maximum value (inclusive)
* @returns A cryptographically secure random integer between min and max (inclusive)
*
* @example
* ```typescript
* // Generates a secure random number (still deterministic with same seed)
* const num = seededSecureInt(42, 1, 1000000);
* ```
*
* @see {@link SecureSeededRNG.nextInt}
* @since 0.1.0
*/
declare function seededSecureInt(seed: number, min: number, max: number): number;
/**
* Generates a cryptographically secure random hex string (seeded)
*
* Creates a temporary SecureSeededRNG instance and generates a
* cryptographically secure hexadecimal string.
*
* This IS safe for:
* - Session tokens
* - API keys
* - Password reset tokens
* - Any security-sensitive strings
*
* @param seed - The seed value for deterministic (but still secure) sequences
* @param length - Number of bytes (each byte becomes 2 hex characters)
* @returns A cryptographically secure hexadecimal string
*
* @example
* ```typescript
* // Generate a 32-byte (64 character) secure hex string
* const token = seededSecureHex(42, 32);
* // Returns: 'a1b2c3d4e5f6...'
*
* // Generate a 16-byte API key
* const apiKey = seededSecureHex(Date.now(), 16);
* ```
*
* @see {@link SecureSeededRNG.nextHex}
* @since 0.1.0
*/
declare function seededSecureHex(seed: number, length: number): string;
export { type RNGOptions, type RNGStats, SecureSeededRNG, SeededRNG, type WeightedItem, createRNG, createSecureRNG, SeededRNG as default, seededFloat, seededInt, seededPick, seededSecureHex, seededSecureInt, seededShuffle };
/**
* Seeded Random Number Generator
*
* ⚠️ **SECURITY WARNING**: The default SeededRNG (LCG) is NOT cryptographically secure!
*
* This library provides TWO RNG implementations:
*
* 1. **SeededRNG** (LCG) - Fast but NOT secure
* - Do NOT use for: passwords, keys, tokens, nonces, security
* - Use for: games, simulations, testing, debugging
*
* 2. **SecureSeededRNG** (ISAAC) - Cryptographically Secure
* - Use for: any security-sensitive operations
* - Deterministic and reproducible like SeededRNG
* - Based on ISAAC cipher algorithm
*
* For cryptographic randomness without seeding:
* - Browser: `crypto.getRandomValues()`
* - Node.js: `crypto.randomBytes()` or `crypto.randomInt()`
*
* @module @opensourceframework/seeded-rng
*/
/**
* Options for weighted random selection
* @since 0.1.0
*/
interface WeightedItem<T> {
/** The item to potentially select */
item: T;
/** The relative weight of this item (higher = more likely) */
weight: number;
}
/**
* Options for creating an RNG instance
* @since 0.1.0
*/
interface RNGOptions {
/** The seed value for deterministic randomness */
seed?: number;
/** Use cryptographically secure RNG (default: false) */
secure?: boolean;
}
/**
* Statistics about the RNG state
* @since 0.1.0
*/
interface RNGStats {
/** The initial seed value */
initialSeed: number;
/** The current seed/state value */
currentSeed: number;
/** Number of random values generated */
iterations: number;
}
/**
* Seeded Random Number Generator for deterministic, reproducible randomness.
*
* Uses the Linear Congruential Generator (LCG) algorithm for consistent,
* reproducible random sequences given the same seed.
*
* ⚠️ **WARNING**: This is NOT cryptographically secure!
* Use SecureSeededRNG for security-sensitive applications.
*
* @example
* ```typescript
* import { SeededRNG } from '@opensourceframework/seeded-rng';
*
* // Create with a specific seed for reproducibility
* const rng = new SeededRNG(12345);
*
* console.log(rng.nextInt(1, 100)); // Always same result for seed 12345
* console.log(rng.next()); // Always same result
*
* // Reset to replay the same sequence
* rng.reset();
* console.log(rng.nextInt(1, 100)); // Same as first call
* ```
* @since 0.1.0
*/
declare class SeededRNG {
private seed;
private initialSeed;
private iterations;
private static readonly A;
private static readonly C;
private static readonly M;
/**
* Creates a new seeded RNG instance
*
* @param seed - Optional seed value. If not provided, generates a random seed
*
* @example
* ```typescript
* // With a specific seed (reproducible)
* const rng1 = new SeededRNG(42);
*
* // Without seed (random each time)
* const rng2 = new SeededRNG();
* ```
*/
constructor(seed?: number);
/**
* Gets the initial seed value (useful for serialization/replay)
*/
getInitialSeed(): number;
/**
* Gets the current seed/state value
*/
getCurrentSeed(): number;
/**
* Sets the current seed/state
*/
setSeed(seed: number): void;
/**
* Gets statistics about the RNG state
*/
getStats(): RNGStats;
/**
* Resets the RNG to its initial state
*/
reset(): void;
/**
* Generates the next random float between 0 (inclusive) and 1 (exclusive)
* Uses LCG algorithm: seed = (seed * a + c) % m
*/
next(): number;
/**
* Generates a random integer in range [min, max] (inclusive)
* @throws {Error} If min is greater than max
*/
nextInt(min: number, max: number): number;
/**
* Generates a random float in range [min, max)
* @throws {Error} If min is greater than max
*/
nextFloat(min: number, max: number): number;
/**
* Returns true with the given probability (0-1)
*/
chance(probability: number): boolean;
/**
* Selects a random element from an array
*/
pick<T>(array: T[]): T | undefined;
/**
* Shuffles an array using the Fisher-Yates algorithm
*/
shuffle<T>(array: T[]): T[];
/**
* Selects a random element based on weights
*/
weightedPick<T>(items: WeightedItem<T>[]): T | undefined;
/**
* Generates a random boolean value
*/
nextBool(probability?: number): boolean;
/**
* Generates a random sign (-1 or 1)
*/
nextSign(): -1 | 1;
/**
* Generates a random hexadecimal string
* ⚠️ NOT for cryptographic use - use SecureSeededRNG for secure hex
*/
nextHex(length: number): string;
/**
* Generates a random UUID-like string (NOT a real UUID!)
* ⚠️ NOT for security use - use crypto.randomUUID() for real UUIDs
*/
nextUUID(): string;
/**
* Creates a new RNG with a random seed derived from this one
*/
fork(): SeededRNG;
}
/**
* Cryptographically Secure Seeded Random Number Generator
*
* Uses the ISAAC (Indirection, Shift, Accumulate, Add, and Count) cipher
* algorithm to generate cryptographically secure pseudo-random numbers.
*
* This is suitable for:
* - Password generation
* - Cryptographic keys
* - Session tokens
* - Nonce generation
* - Any security-sensitive operations
*
* Like SeededRNG, this is deterministic - the same seed produces the same sequence.
*
* @example
* ```typescript
* import { SecureSeededRNG } from '@opensourceframework/seeded-rng';
*
* // Create with a specific seed for reproducibility
* const rng = new SecureSeededRNG(12345);
*
* console.log(rng.nextInt(1, 100)); // Always same result for seed 12345
* console.log(rng.nextHex(32)); // Always same secure hex for seed 12345
*
* // Reset to replay the same sequence
* rng.reset();
* console.log(rng.nextInt(1, 100)); // Same as first call
* ```
*
* @example
* ```typescript
* // Generate a secure random password
* const rng = new SecureSeededRNG();
* const password = rng.nextHex(32); // 32 bytes of secure randomness
* ```
* @since 0.1.0
*/
declare class SecureSeededRNG {
private seed;
private initialSeed;
private iterations;
private randRsl;
private randCnt;
private randA;
private randB;
private randC;
/**
* Creates a new secure seeded RNG instance
*
* @param seed - Optional seed value. If not provided, uses crypto.getRandomValues()
*
* @example
* ```typescript
* // With a specific seed (reproducible)
* const rng1 = new SecureSeededRNG(42);
*
* // Without seed (cryptographically random each time)
* const rng2 = new SecureSeededRNG();
* ```
*/
constructor(seed?: number);
/**
* Initialize ISAAC with a seed
*/
private isaacSeed;
/**
* ISAAC algorithm - generates 256 random 32-bit values
*/
private isaac;
/**
* Get next 32-bit random value
*/
private rand;
/**
* Gets the initial seed value
*/
getInitialSeed(): number;
/**
* Gets the current state value
*/
getCurrentSeed(): number;
/**
* Sets the current seed/state
*/
setSeed(seed: number): void;
/**
* Gets statistics about the RNG state
*/
getStats(): RNGStats;
/**
* Resets the RNG to its initial state
*/
reset(): void;
/**
* Generates the next random float between 0 (inclusive) and 1 (exclusive)
*/
next(): number;
/**
* Generates a random integer in range [min, max] (inclusive)
* @throws {Error} If min is greater than max
*/
nextInt(min: number, max: number): number;
/**
* Generates a random float in range [min, max)
* @throws {Error} If min is greater than max
*/
nextFloat(min: number, max: number): number;
/**
* Returns true with the given probability (0-1)
* @throws {Error} If probability is not between 0 and 1
*/
chance(probability: number): boolean;
/**
* Selects a random element from an array
*/
pick<T>(array: T[]): T | undefined;
/**
* Shuffles an array using the Fisher-Yates algorithm
*/
shuffle<T>(array: T[]): T[];
/**
* Selects a random element based on weights
*/
weightedPick<T>(items: WeightedItem<T>[]): T | undefined;
/**
* Generates a random boolean value
*/
nextBool(probability?: number): boolean;
/**
* Generates a random sign (-1 or 1)
*/
nextSign(): -1 | 1;
/**
* Generates a cryptographically secure random hexadecimal string
*
* This IS safe for:
* - Session tokens
* - API keys
* - Reset tokens
* - Any security-sensitive strings
*
* When seeded, always uses ISAAC for deterministic output.
*
* @param length - Number of bytes (each byte becomes 2 hex chars)
*/
nextHex(length: number): string;
/**
* Generates a cryptographically secure random byte array
*
* @param length - Number of random bytes to generate
*/
nextBytes(length: number): Uint8Array;
/**
* Generates a cryptographically secure random Base64 string
*
* @param length - Number of random bytes before encoding
*/
nextBase64(length: number): string;
/**
* Generates a random UUID v4 (cryptographically secure)
*
* Uses ISAAC for deterministic UUID generation when seeded.
*/
nextUUID(): string;
/**
* Creates a new SecureSeededRNG with a random seed derived from this one
*/
fork(): SecureSeededRNG;
}
/**
* Creates a new SeededRNG instance (fast, NOT cryptographically secure)
*
* This is a convenience factory function that creates a new SeededRNG instance.
* The SeededRNG uses a Linear Congruential Generator (LCG) algorithm which is
* fast but NOT suitable for security-sensitive operations.
*
* @param seed - Optional seed value. If not provided, a random seed will be generated.
* Pass `null` to explicitly indicate no seed is provided.
* @returns A new SeededRNG instance initialized with the provided or generated seed
*
* @example
* ```typescript
* // With a specific seed (reproducible sequences)
* const rng = createRNG(42);
* console.log(rng.nextInt(1, 100)); // Always returns the same value
*
* // Without seed (random each time)
* const rng2 = createRNG();
* ```
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random|Math.random}
* @group Seeded RNG
* @since 0.1.0
*/
declare function createRNG(seed?: number | null): SeededRNG;
/**
* Creates a new SecureSeededRNG instance (cryptographically secure)
*
* This is a convenience factory function that creates a new SecureSeededRNG instance.
* The SecureSeededRNG uses the ISAAC cipher algorithm which is cryptographically
* secure and suitable for security-sensitive operations like password generation,
* token creation, and cryptographic key derivation.
*
* @param seed - Optional seed value for deterministic sequences.
* If not provided, a cryptographically random seed will be generated
* using `crypto.getRandomValues()` where available.
* Pass `null` to explicitly indicate no seed is provided.
* @returns A new SecureSeededRNG instance initialized with the provided or generated seed
*
* @example
* ```typescript
* // With a specific seed (reproducible sequences)
* const rng = createSecureRNG(42);
* console.log(rng.nextHex(16)); // Always returns the same value
*
* // Without seed (cryptographically random each time)
* const rng2 = createSecureRNG();
* const password = rng2.nextHex(32); // 32-byte secure password
* ```
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues|crypto.getRandomValues}
* @group Secure RNG
* @since 0.1.0
*/
declare function createSecureRNG(seed?: number | null): SecureSeededRNG;
/**
* Generates a single random integer with a seed (one-shot, NOT secure)
*
* Creates a temporary SeededRNG instance, generates a single random integer
* in the specified range [min, max], and returns the result.
*
* ⚠️ This is NOT cryptographically secure. Use for games, testing, or
* non-security-related randomness only.
*
* @param seed - The seed value for deterministic randomness
* @param min - Minimum value (inclusive)
* @param max - Maximum value (inclusive)
* @returns A random integer between min and max (inclusive)
*
* @example
* ```typescript
* // Always returns the same value for the same seed
* console.log(seededInt(12345, 1, 100)); // Always returns 38 (for example)
* ```
*
* @see {@link SeededRNG.nextInt}
* @since 0.1.0
*/
declare function seededInt(seed: number, min: number, max: number): number;
/**
* Generates a single random float with a seed (one-shot, NOT secure)
*
* Creates a temporary SeededRNG instance, generates a single random float
* in the specified range [min, max), and returns the result.
*
* ⚠️ This is NOT cryptographically secure. Use for games, testing, or
* non-security-related randomness only.
*
* @param seed - The seed value for deterministic randomness
* @param min - Minimum value (inclusive)
* @param max - Maximum value (exclusive)
* @returns A random float between min (inclusive) and max (exclusive)
*
* @example
* ```typescript
* // Always returns the same value for the same seed
* console.log(seededFloat(12345, 0.0, 1.0)); // Always returns 0.83... (for example)
* ```
*
* @see {@link SeededRNG.nextFloat}
* @since 0.1.0
*/
declare function seededFloat(seed: number, min: number, max: number): number;
/**
* Shuffles an array with a seed (one-shot, NOT secure)
*
* Creates a temporary SeededRNG instance, shuffles the array using the
* Fisher-Yates algorithm with the seeded random number generator, and
* returns a new shuffled array.
*
* ⚠️ This is NOT cryptographically secure. Use for games, testing, or
* non-security-related randomness only.
*
* @param seed - The seed value for deterministic shuffling
* @param array - The array to shuffle
* @returns A new array with elements in random order (deterministic based on seed)
*
* @example
* ```typescript
* // Always produces the same shuffle for the same seed
* const result = seededShuffle(42, ['a', 'b', 'c', 'd']);
* // Result is always: ['c', 'a', 'd', 'b'] (for example)
* ```
*
* @see {@link SeededRNG.shuffle}
* @since 0.1.0
*/
declare function seededShuffle<T>(seed: number, array: T[]): T[];
/**
* Picks a random element with a seed (one-shot, NOT secure)
*
* Creates a temporary SeededRNG instance and selects a random element
* from the provided array.
*
* ⚠️ This is NOT cryptographically secure. Use for games, testing, or
* non-security-related randomness only.
*
* @param seed - The seed value for deterministic selection
* @param array - The array to pick from
* @returns A randomly selected element from the array, or undefined if empty
*
* @example
* ```typescript
* // Always picks the same element for the same seed
* const item = seededPick(42, ['apple', 'banana', 'cherry']);
* // Always returns 'banana' (for example)
*
* // Returns undefined for empty arrays
* const empty = seededPick(1, []); // Returns undefined
* ```
*
* @see {@link SeededRNG.pick}
* @since 0.1.0
*/
declare function seededPick<T>(seed: number, array: T[]): T | undefined;
/**
* Generates a single cryptographically secure random integer with a seed
*
* Creates a temporary SecureSeededRNG instance and generates a single
* random integer in the specified range [min, max].
*
* This IS cryptographically secure and suitable for security-sensitive
* operations like generating random IDs, tokens, or any value that
* should not be predictable.
*
* @param seed - The seed value for deterministic (but still secure) sequences
* @param min - Minimum value (inclusive)
* @param max - Maximum value (inclusive)
* @returns A cryptographically secure random integer between min and max (inclusive)
*
* @example
* ```typescript
* // Generates a secure random number (still deterministic with same seed)
* const num = seededSecureInt(42, 1, 1000000);
* ```
*
* @see {@link SecureSeededRNG.nextInt}
* @since 0.1.0
*/
declare function seededSecureInt(seed: number, min: number, max: number): number;
/**
* Generates a cryptographically secure random hex string (seeded)
*
* Creates a temporary SecureSeededRNG instance and generates a
* cryptographically secure hexadecimal string.
*
* This IS safe for:
* - Session tokens
* - API keys
* - Password reset tokens
* - Any security-sensitive strings
*
* @param seed - The seed value for deterministic (but still secure) sequences
* @param length - Number of bytes (each byte becomes 2 hex characters)
* @returns A cryptographically secure hexadecimal string
*
* @example
* ```typescript
* // Generate a 32-byte (64 character) secure hex string
* const token = seededSecureHex(42, 32);
* // Returns: 'a1b2c3d4e5f6...'
*
* // Generate a 16-byte API key
* const apiKey = seededSecureHex(Date.now(), 16);
* ```
*
* @see {@link SecureSeededRNG.nextHex}
* @since 0.1.0
*/
declare function seededSecureHex(seed: number, length: number): string;
export { type RNGOptions, type RNGStats, SecureSeededRNG, SeededRNG, type WeightedItem, createRNG, createSecureRNG, SeededRNG as default, seededFloat, seededInt, seededPick, seededSecureHex, seededSecureInt, seededShuffle };
/**
* @opensourceframework/seeded-rng
* Seeded random number generator for reproducible randomness
*
* ⚠️ WARNING: This is NOT cryptographically secure!
* Do NOT use for security-sensitive operations like:
* - Password generation
* - Cryptographic keys
* - Session tokens
* - Any security-related randomness
*
* Use crypto.getRandomValues() or Node.js crypto module instead.
*
* @license MIT
*/
// src/index.ts
var SeededRNG = class _SeededRNG {
seed;
initialSeed;
iterations = 0;
// LCG parameters (using values from Numerical Recipes)
static A = 9301;
static C = 49297;
static M = 233280;
/**
* Creates a new seeded RNG instance
*
* @param seed - Optional seed value. If not provided, generates a random seed
*
* @example
* ```typescript
* // With a specific seed (reproducible)
* const rng1 = new SeededRNG(42);
*
* // Without seed (random each time)
* const rng2 = new SeededRNG();
* ```
*/
constructor(seed) {
this.initialSeed = seed ?? Math.floor(Math.random() * 2147483647);
this.seed = this.initialSeed;
}
/**
* Gets the initial seed value (useful for serialization/replay)
*/
getInitialSeed() {
return this.initialSeed;
}
/**
* Gets the current seed/state value
*/
getCurrentSeed() {
return this.seed;
}
/**
* Sets the current seed/state
*/
setSeed(seed) {
this.seed = seed;
}
/**
* Gets statistics about the RNG state
*/
getStats() {
return {
initialSeed: this.initialSeed,
currentSeed: this.seed,
iterations: this.iterations
};
}
/**
* Resets the RNG to its initial state
*/
reset() {
this.seed = this.initialSeed;
this.iterations = 0;
}
/**
* Generates the next random float between 0 (inclusive) and 1 (exclusive)
* Uses LCG algorithm: seed = (seed * a + c) % m
*/
next() {
this.seed = (this.seed * _SeededRNG.A + _SeededRNG.C) % _SeededRNG.M;
this.iterations++;
return this.seed / _SeededRNG.M;
}
/**
* Generates a random integer in range [min, max] (inclusive)
* @throws {Error} If min is greater than max
*/
nextInt(min, max) {
if (min > max) {
throw new Error("min must be less than or equal to max");
}
return Math.floor(this.next() * (max - min + 1)) + min;
}
/**
* Generates a random float in range [min, max)
* @throws {Error} If min is greater than max
*/
nextFloat(min, max) {
if (min > max) {
throw new Error("min must be less than max");
}
return this.next() * (max - min) + min;
}
/**
* Returns true with the given probability (0-1)
*/
chance(probability) {
return this.next() < probability;
}
/**
* Selects a random element from an array
*/
pick(array) {
if (array.length === 0) return void 0;
return array[this.nextInt(0, array.length - 1)];
}
/**
* Shuffles an array using the Fisher-Yates algorithm
*/
shuffle(array) {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = this.nextInt(0, i);
const temp = result[i];
result[i] = result[j];
result[j] = temp;
}
return result;
}
/**
* Selects a random element based on weights
*/
weightedPick(items) {
if (items.length === 0) return void 0;
const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);
let random = this.next() * totalWeight;
for (const item of items) {
random -= item.weight;
if (random <= 0) {
return item.item;
}
}
return items[items.length - 1]?.item;
}
/**
* Generates a random boolean value
*/
nextBool(probability = 0.5) {
return this.chance(probability);
}
/**
* Generates a random sign (-1 or 1)
*/
nextSign() {
return this.chance(0.5) ? 1 : -1;
}
/**
* Generates a random hexadecimal string
* ⚠️ NOT for cryptographic use - use SecureSeededRNG for secure hex
*/
nextHex(length) {
const chars = "0123456789abcdef";
const result = new Array(length);
for (let i = 0; i < length; i++) {
result[i] = chars[this.nextInt(0, 15)];
}
return result.join("");
}
/**
* Generates a random UUID-like string (NOT a real UUID!)
* ⚠️ NOT for security use - use crypto.randomUUID() for real UUIDs
*/
nextUUID() {
return `${this.nextHex(8)}-${this.nextHex(4)}-${this.nextHex(4)}-${this.nextHex(4)}-${this.nextHex(12)}`;
}
/**
* Creates a new RNG with a random seed derived from this one
*/
fork() {
return new _SeededRNG(this.nextInt(0, 2147483647));
}
};
var SecureSeededRNG = class _SecureSeededRNG {
seed;
initialSeed;
iterations = 0;
// ISAAC state
randRsl;
randCnt;
randA;
randB;
randC;
/**
* Creates a new secure seeded RNG instance
*
* @param seed - Optional seed value. If not provided, uses crypto.getRandomValues()
*
* @example
* ```typescript
* // With a specific seed (reproducible)
* const rng1 = new SecureSeededRNG(42);
*
* // Without seed (cryptographically random each time)
* const rng2 = new SecureSeededRNG();
* ```
*/
constructor(seed) {
this.randRsl = new Array(256);
this.randCnt = 256;
this.randA = 0;
this.randB = 0;
this.randC = 0;
if (seed === void 0) {
let randomSeed = Math.floor(Math.random() * 4294967296);
try {
const array = new Uint32Array(1);
if (typeof globalThis !== "undefined" && "crypto" in globalThis) {
const maybeCrypto = globalThis;
maybeCrypto.crypto?.getRandomValues?.(array);
if (array[0] !== void 0) {
randomSeed = array[0];
}
}
} catch (error) {
console.warn("SecureSeededRNG: crypto.getRandomValues not available, falling back to Math.random:", error);
}
seed = randomSeed;
}
this.initialSeed = seed;
this.seed = seed;
this.isaacSeed(seed);
}
/**
* Initialize ISAAC with a seed
*/
isaacSeed(seed) {
const seedArray = new Array(256);
const GOLDEN_RATIO = 2654435769;
let mix = seed;
for (let i = 0; i < 256; i++) {
mix = (mix ^ mix >>> 16) * GOLDEN_RATIO | 0;
seedArray[i] = mix;
}
this.randA = seed;
this.randB = seed ^ 2654435769;
this.randC = seed ^ 2654435769;
for (let i = 0; i < 256; i++) {
this.randRsl[i] = seedArray[i] ?? 0;
}
this.randCnt = 256;
this.isaac();
}
/**
* ISAAC algorithm - generates 256 random 32-bit values
*/
isaac() {
let i, y;
this.randB = this.randB + (this.randC + 1) | 0 | 0;
this.randC = this.randC + 1 | 0;
for (i = 0; i < 256; i++) {
this.randRsl[i];
switch (i & 3) {
case 0:
this.randA = this.randA ^ this.randA << 13 | 0;
break;
case 1:
this.randA = this.randA ^ this.randA >>> 6 | 0;
break;
case 2:
this.randA = this.randA ^ this.randA << 2 | 0;
break;
case 3:
this.randA = this.randA ^ this.randA >>> 16 | 0;
break;
}
const rslIdx = i + 128 & 255;
const rslVal = this.randRsl[rslIdx] ?? 0;
y = (rslVal + this.randA | 0) + this.randB | 0;
this.randRsl[i] = y;
const idx2 = y >>> 2 & 255;
const rslVal2 = this.randRsl[idx2] ?? 0;
this.randB = rslVal2 + this.randA + this.randB | 0 | 0;
}
}
/**
* Get next 32-bit random value
*/
rand() {
if (this.randCnt === 0) {
this.isaac();
this.randCnt = 256;
}
this.randCnt--;
this.iterations++;
const result = this.randRsl[this.randCnt];
return result ?? 0;
}
/**
* Gets the initial seed value
*/
getInitialSeed() {
return this.initialSeed;
}
/**
* Gets the current state value
*/
getCurrentSeed() {
return this.seed;
}
/**
* Sets the current seed/state
*/
setSeed(seed) {
this.seed = seed;
this.isaacSeed(seed);
}
/**
* Gets statistics about the RNG state
*/
getStats() {
return {
initialSeed: this.initialSeed,
currentSeed: this.seed,
iterations: this.iterations
};
}
/**
* Resets the RNG to its initial state
*/
reset() {
this.seed = this.initialSeed;
this.iterations = 0;
this.isaacSeed(this.initialSeed);
}
/**
* Generates the next random float between 0 (inclusive) and 1 (exclusive)
*/
next() {
return (this.rand() >>> 0) / 4294967296;
}
/**
* Generates a random integer in range [min, max] (inclusive)
* @throws {Error} If min is greater than max
*/
nextInt(min, max) {
if (min > max) {
throw new Error("min must be less than or equal to max");
}
return Math.floor(this.next() * (max - min + 1)) + min;
}
/**
* Generates a random float in range [min, max)
* @throws {Error} If min is greater than max
*/
nextFloat(min, max) {
if (min > max) {
throw new Error("min must be less than max");
}
return this.next() * (max - min) + min;
}
/**
* Returns true with the given probability (0-1)
* @throws {Error} If probability is not between 0 and 1
*/
chance(probability) {
if (probability < 0 || probability > 1) {
throw new Error("probability must be between 0 and 1");
}
return this.next() < probability;
}
/**
* Selects a random element from an array
*/
pick(array) {
if (array.length === 0) return void 0;
return array[this.nextInt(0, array.length - 1)];
}
/**
* Shuffles an array using the Fisher-Yates algorithm
*/
shuffle(array) {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = this.nextInt(0, i);
const temp = result[i];
result[i] = result[j];
result[j] = temp;
}
return result;
}
/**
* Selects a random element based on weights
*/
weightedPick(items) {
if (items.length === 0) return void 0;
const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);
let random = this.next() * totalWeight;
for (const item of items) {
random -= item.weight;
if (random <= 0) {
return item.item;
}
}
return items[items.length - 1]?.item;
}
/**
* Generates a random boolean value
*/
nextBool(probability = 0.5) {
return this.chance(probability);
}
/**
* Generates a random sign (-1 or 1)
*/
nextSign() {
return this.chance(0.5) ? 1 : -1;
}
/**
* Generates a cryptographically secure random hexadecimal string
*
* This IS safe for:
* - Session tokens
* - API keys
* - Reset tokens
* - Any security-sensitive strings
*
* When seeded, always uses ISAAC for deterministic output.
*
* @param length - Number of bytes (each byte becomes 2 hex chars)
*/
nextHex(length) {
const chars = "0123456789abcdef";
const result = new Array(length * 2);
let idx = 0;
for (let i = 0; i < length; i++) {
const byte = this.rand() & 255;
result[idx++] = chars[byte >> 4 & 15];
result[idx++] = chars[byte & 15];
}
return result.join("");
}
/**
* Generates a cryptographically secure random byte array
*
* @param length - Number of random bytes to generate
*/
nextBytes(length) {
const bytes = new Uint8Array(length);
for (let i = 0; i < length; i++) {
bytes[i] = this.rand() & 255;
}
return bytes;
}
/**
* Generates a cryptographically secure random Base64 string
*
* @param length - Number of random bytes before encoding
*/
nextBase64(length) {
const bytes = this.nextBytes(length);
const binary = new Array(bytes.length);
for (let i = 0; i < bytes.length; i++) {
binary[i] = String.fromCharCode(bytes[i] ?? 0);
}
return btoa(binary.join(""));
}
/**
* Generates a random UUID v4 (cryptographically secure)
*
* Uses ISAAC for deterministic UUID generation when seeded.
*/
nextUUID() {
const bytes = new Uint8Array(16);
for (let i = 0; i < 16; i++) {
bytes[i] = this.rand() & 255;
}
const byte6 = bytes[6] ?? 0;
const byte8 = bytes[8] ?? 0;
bytes[6] = byte6 & 15 | 64;
bytes[8] = byte8 & 63 | 128;
const hex = Array.from(bytes).map((b) => (b ?? 0).toString(16).padStart(2, "0")).join("");
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
}
/**
* Creates a new SecureSeededRNG with a random seed derived from this one
*/
fork() {
return new _SecureSeededRNG(this.nextInt(0, 4294967295));
}
};
function createRNG(seed) {
return new SeededRNG(seed ?? void 0);
}
function createSecureRNG(seed) {
return new SecureSeededRNG(seed ?? void 0);
}
function seededInt(seed, min, max) {
const rng = new SeededRNG(seed);
return rng.nextInt(min, max);
}
function seededFloat(seed, min, max) {
const rng = new SeededRNG(seed);
return rng.nextFloat(min, max);
}
function seededShuffle(seed, array) {
const rng = new SeededRNG(seed);
return rng.shuffle(array);
}
function seededPick(seed, array) {
const rng = new SeededRNG(seed);
return rng.pick(array);
}
function seededSecureInt(seed, min, max) {
const rng = new SecureSeededRNG(seed);
return rng.nextInt(min, max);
}
function seededSecureHex(seed, length) {
const rng = new SecureSeededRNG(seed);
return rng.nextHex(length);
}
export { SecureSeededRNG, SeededRNG, createRNG, createSecureRNG, SeededRNG as default, seededFloat, seededInt, seededPick, seededSecureHex, seededSecureInt, seededShuffle };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Seeded Random Number Generator\n * \n * ⚠️ **SECURITY WARNING**: The default SeededRNG (LCG) is NOT cryptographically secure!\n * \n * This library provides TWO RNG implementations:\n * \n * 1. **SeededRNG** (LCG) - Fast but NOT secure\n * - Do NOT use for: passwords, keys, tokens, nonces, security\n * - Use for: games, simulations, testing, debugging\n * \n * 2. **SecureSeededRNG** (ISAAC) - Cryptographically Secure\n * - Use for: any security-sensitive operations\n * - Deterministic and reproducible like SeededRNG\n * - Based on ISAAC cipher algorithm\n * \n * For cryptographic randomness without seeding:\n * - Browser: `crypto.getRandomValues()`\n * - Node.js: `crypto.randomBytes()` or `crypto.randomInt()`\n * \n * @module @opensourceframework/seeded-rng\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Options for weighted random selection\n * @since 0.1.0\n */\nexport interface WeightedItem<T> {\n /** The item to potentially select */\n item: T;\n /** The relative weight of this item (higher = more likely) */\n weight: number;\n}\n\n/**\n * Options for creating an RNG instance\n * @since 0.1.0\n */\nexport interface RNGOptions {\n /** The seed value for deterministic randomness */\n seed?: number;\n /** Use cryptographically secure RNG (default: false) */\n secure?: boolean;\n}\n\n/**\n * Statistics about the RNG state\n * @since 0.1.0\n */\nexport interface RNGStats {\n /** The initial seed value */\n initialSeed: number;\n /** The current seed/state value */\n currentSeed: number;\n /** Number of random values generated */\n iterations: number;\n}\n\n// ============================================================================\n// SeededRNG Class (Fast, NOT Cryptographically Secure)\n// ============================================================================\n\n/**\n * Seeded Random Number Generator for deterministic, reproducible randomness.\n * \n * Uses the Linear Congruential Generator (LCG) algorithm for consistent,\n * reproducible random sequences given the same seed.\n * \n * ⚠️ **WARNING**: This is NOT cryptographically secure!\n * Use SecureSeededRNG for security-sensitive applications.\n * \n * @example\n * ```typescript\n * import { SeededRNG } from '@opensourceframework/seeded-rng';\n * \n * // Create with a specific seed for reproducibility\n * const rng = new SeededRNG(12345);\n * \n * console.log(rng.nextInt(1, 100)); // Always same result for seed 12345\n * console.log(rng.next()); // Always same result\n * \n * // Reset to replay the same sequence\n * rng.reset();\n * console.log(rng.nextInt(1, 100)); // Same as first call\n * ```\n * @since 0.1.0\n */\nexport class SeededRNG {\n private seed: number;\n private initialSeed: number;\n private iterations: number = 0;\n\n // LCG parameters (using values from Numerical Recipes)\n private static readonly A = 9301;\n private static readonly C = 49297;\n private static readonly M = 233280;\n\n /**\n * Creates a new seeded RNG instance\n * \n * @param seed - Optional seed value. If not provided, generates a random seed\n * \n * @example\n * ```typescript\n * // With a specific seed (reproducible)\n * const rng1 = new SeededRNG(42);\n * \n * // Without seed (random each time)\n * const rng2 = new SeededRNG();\n * ```\n */\n constructor(seed?: number) {\n this.initialSeed = seed ?? Math.floor(Math.random() * 2147483647);\n this.seed = this.initialSeed;\n }\n\n /**\n * Gets the initial seed value (useful for serialization/replay)\n */\n getInitialSeed(): number {\n return this.initialSeed;\n }\n\n /**\n * Gets the current seed/state value\n */\n getCurrentSeed(): number {\n return this.seed;\n }\n\n /**\n * Sets the current seed/state\n */\n setSeed(seed: number): void {\n this.seed = seed;\n }\n\n /**\n * Gets statistics about the RNG state\n */\n getStats(): RNGStats {\n return {\n initialSeed: this.initialSeed,\n currentSeed: this.seed,\n iterations: this.iterations,\n };\n }\n\n /**\n * Resets the RNG to its initial state\n */\n reset(): void {\n this.seed = this.initialSeed;\n this.iterations = 0;\n }\n\n /**\n * Generates the next random float between 0 (inclusive) and 1 (exclusive)\n * Uses LCG algorithm: seed = (seed * a + c) % m\n */\n next(): number {\n this.seed = (this.seed * SeededRNG.A + SeededRNG.C) % SeededRNG.M;\n this.iterations++;\n return this.seed / SeededRNG.M;\n }\n\n /**\n * Generates a random integer in range [min, max] (inclusive)\n * @throws {Error} If min is greater than max\n */\n nextInt(min: number, max: number): number {\n if (min > max) {\n throw new Error('min must be less than or equal to max');\n }\n return Math.floor(this.next() * (max - min + 1)) + min;\n }\n\n /**\n * Generates a random float in range [min, max)\n * @throws {Error} If min is greater than max\n */\n nextFloat(min: number, max: number): number {\n if (min > max) {\n throw new Error('min must be less than max');\n }\n return this.next() * (max - min) + min;\n }\n\n /**\n * Returns true with the given probability (0-1)\n */\n chance(probability: number): boolean {\n return this.next() < probability;\n }\n\n /**\n * Selects a random element from an array\n */\n pick<T>(array: T[]): T | undefined {\n if (array.length === 0) return undefined;\n return array[this.nextInt(0, array.length - 1)];\n }\n\n /**\n * Shuffles an array using the Fisher-Yates algorithm\n */\n shuffle<T>(array: T[]): T[] {\n const result = [...array];\n for (let i = result.length - 1; i > 0; i--) {\n const j = this.nextInt(0, i);\n const temp = result[i];\n result[i] = result[j] as T;\n result[j] = temp as T;\n }\n return result;\n }\n\n /**\n * Selects a random element based on weights\n */\n weightedPick<T>(items: WeightedItem<T>[]): T | undefined {\n if (items.length === 0) return undefined;\n\n const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);\n let random = this.next() * totalWeight;\n\n for (const item of items) {\n random -= item.weight;\n if (random <= 0) {\n return item.item;\n }\n }\n\n return items[items.length - 1]?.item;\n }\n\n /**\n * Generates a random boolean value\n */\n nextBool(probability: number = 0.5): boolean {\n return this.chance(probability);\n }\n\n /**\n * Generates a random sign (-1 or 1)\n */\n nextSign(): -1 | 1 {\n return this.chance(0.5) ? 1 : -1;\n }\n\n /**\n * Generates a random hexadecimal string\n * ⚠️ NOT for cryptographic use - use SecureSeededRNG for secure hex\n */\n nextHex(length: number): string {\n const chars = '0123456789abcdef';\n const result = new Array(length);\n for (let i = 0; i < length; i++) {\n result[i] = chars[this.nextInt(0, 15)];\n }\n return result.join('');\n }\n\n /**\n * Generates a random UUID-like string (NOT a real UUID!)\n * ⚠️ NOT for security use - use crypto.randomUUID() for real UUIDs\n */\n nextUUID(): string {\n return `${this.nextHex(8)}-${this.nextHex(4)}-${this.nextHex(4)}-${this.nextHex(4)}-${this.nextHex(12)}`;\n }\n\n /**\n * Creates a new RNG with a random seed derived from this one\n */\n fork(): SeededRNG {\n return new SeededRNG(this.nextInt(0, 2147483647));\n }\n}\n\n// ============================================================================\n// SecureSeededRNG Class (Cryptographically Secure - ISAAC)\n// ============================================================================\n\n/**\n * Cryptographically Secure Seeded Random Number Generator\n * \n * Uses the ISAAC (Indirection, Shift, Accumulate, Add, and Count) cipher\n * algorithm to generate cryptographically secure pseudo-random numbers.\n * \n * This is suitable for:\n * - Password generation\n * - Cryptographic keys\n * - Session tokens\n * - Nonce generation\n * - Any security-sensitive operations\n * \n * Like SeededRNG, this is deterministic - the same seed produces the same sequence.\n * \n * @example\n * ```typescript\n * import { SecureSeededRNG } from '@opensourceframework/seeded-rng';\n * \n * // Create with a specific seed for reproducibility\n * const rng = new SecureSeededRNG(12345);\n * \n * console.log(rng.nextInt(1, 100)); // Always same result for seed 12345\n * console.log(rng.nextHex(32)); // Always same secure hex for seed 12345\n * \n * // Reset to replay the same sequence\n * rng.reset();\n * console.log(rng.nextInt(1, 100)); // Same as first call\n * ```\n * \n * @example\n * ```typescript\n * // Generate a secure random password\n * const rng = new SecureSeededRNG();\n * const password = rng.nextHex(32); // 32 bytes of secure randomness\n * ```\n * @since 0.1.0\n */\nexport class SecureSeededRNG {\n private seed: number;\n private initialSeed: number;\n private iterations: number = 0;\n \n // ISAAC state\n private randRsl: number[];\n private randCnt: number;\n private randA: number;\n private randB: number;\n private randC: number;\n\n /**\n * Creates a new secure seeded RNG instance\n * \n * @param seed - Optional seed value. If not provided, uses crypto.getRandomValues()\n * \n * @example\n * ```typescript\n * // With a specific seed (reproducible)\n * const rng1 = new SecureSeededRNG(42);\n * \n * // Without seed (cryptographically random each time)\n * const rng2 = new SecureSeededRNG();\n * ```\n */\n constructor(seed?: number) {\n // Initialize arrays\n this.randRsl = new Array(256);\n this.randCnt = 256;\n this.randA = 0;\n this.randB = 0;\n this.randC = 0;\n \n // Use crypto API if available for initial random seed\n if (seed === undefined) {\n let randomSeed = Math.floor(Math.random() * 4294967296);\n \n try {\n // Try to use crypto.getRandomValues\n const array = new Uint32Array(1);\n // Use type-safe check for crypto.getRandomValues\n if (typeof globalThis !== 'undefined' && 'crypto' in globalThis) {\n const maybeCrypto = globalThis as { crypto?: { getRandomValues?: (arr: Uint32Array) => Uint32Array } };\n maybeCrypto.crypto?.getRandomValues?.(array);\n if (array[0] !== undefined) {\n randomSeed = array[0];\n }\n }\n } catch (error) {\n console.warn('SecureSeededRNG: crypto.getRandomValues not available, falling back to Math.random:', error);\n }\n \n seed = randomSeed;\n }\n \n this.initialSeed = seed;\n this.seed = seed;\n this.isaacSeed(seed);\n }\n\n /**\n * Initialize ISAAC with a seed\n */\n private isaacSeed(seed: number): void {\n // Generate 256 32-bit values from the seed using a mixing function\n const seedArray: number[] = new Array(256);\n \n // Simple seed expansion - mix the seed with golden ratio\n const GOLDEN_RATIO = 0x9e3779b9;\n let mix = seed;\n \n for (let i = 0; i < 256; i++) {\n mix = (mix ^ (mix >>> 16)) * GOLDEN_RATIO | 0;\n seedArray[i] = mix;\n }\n \n // Initialize randA, randB, randC with values derived from seed\n this.randA = seed;\n this.randB = seed ^ 0x9e3779b9;\n this.randC = seed ^ 0x9e3779b9;\n \n // Initialize randRsl with seed array\n for (let i = 0; i < 256; i++) {\n this.randRsl[i] = seedArray[i] ?? 0;\n }\n \n // Initialize randCnt\n this.randCnt = 256;\n \n // First round of ISAAC - warm up\n this.isaac();\n }\n\n /**\n * ISAAC algorithm - generates 256 random 32-bit values\n */\n private isaac(): void {\n let i, _x, y;\n \n this.randB = (this.randB + (this.randC + 1) | 0) | 0;\n this.randC = (this.randC + 1) | 0;\n \n for (i = 0; i < 256; i++) {\n _x = this.randRsl[i];\n \n switch (i & 3) {\n case 0:\n this.randA = (this.randA ^ (this.randA << 13)) | 0;\n break;\n case 1:\n this.randA = (this.randA ^ (this.randA >>> 6)) | 0;\n break;\n case 2:\n this.randA = (this.randA ^ (this.randA << 2)) | 0;\n break;\n case 3:\n this.randA = (this.randA ^ (this.randA >>> 16)) | 0;\n break;\n }\n \n const rslIdx = (i + 128) & 0xff;\n const rslVal = this.randRsl[rslIdx] ?? 0;\n y = ((rslVal + this.randA) | 0) + this.randB | 0;\n \n this.randRsl[i] = y;\n \n const idx2 = (y >>> 2) & 0xff;\n const rslVal2 = this.randRsl[idx2] ?? 0;\n this.randB = ((rslVal2 + this.randA + this.randB) | 0) | 0;\n }\n }\n\n /**\n * Get next 32-bit random value\n */\n private rand(): number {\n if (this.randCnt === 0) {\n this.isaac();\n this.randCnt = 256;\n }\n \n this.randCnt--;\n this.iterations++;\n \n const result = this.randRsl[this.randCnt];\n return result ?? 0;\n }\n\n /**\n * Gets the initial seed value\n */\n getInitialSeed(): number {\n return this.initialSeed;\n }\n\n /**\n * Gets the current state value\n */\n getCurrentSeed(): number {\n return this.seed;\n }\n\n /**\n * Sets the current seed/state\n */\n setSeed(seed: number): void {\n this.seed = seed;\n this.isaacSeed(seed);\n }\n\n /**\n * Gets statistics about the RNG state\n */\n getStats(): RNGStats {\n return {\n initialSeed: this.initialSeed,\n currentSeed: this.seed,\n iterations: this.iterations,\n };\n }\n\n /**\n * Resets the RNG to its initial state\n */\n reset(): void {\n this.seed = this.initialSeed;\n this.iterations = 0;\n this.isaacSeed(this.initialSeed);\n }\n\n /**\n * Generates the next random float between 0 (inclusive) and 1 (exclusive)\n */\n next(): number {\n // Use >>> 0 to convert signed 32-bit int to unsigned before division\n return (this.rand() >>> 0) / 4294967296;\n }\n\n /**\n * Generates a random integer in range [min, max] (inclusive)\n * @throws {Error} If min is greater than max\n */\n nextInt(min: number, max: number): number {\n if (min > max) {\n throw new Error('min must be less than or equal to max');\n }\n return Math.floor(this.next() * (max - min + 1)) + min;\n }\n\n /**\n * Generates a random float in range [min, max)\n * @throws {Error} If min is greater than max\n */\n nextFloat(min: number, max: number): number {\n if (min > max) {\n throw new Error('min must be less than max');\n }\n return this.next() * (max - min) + min;\n }\n\n /**\n * Returns true with the given probability (0-1)\n * @throws {Error} If probability is not between 0 and 1\n */\n chance(probability: number): boolean {\n if (probability < 0 || probability > 1) {\n throw new Error('probability must be between 0 and 1');\n }\n return this.next() < probability;\n }\n\n /**\n * Selects a random element from an array\n */\n pick<T>(array: T[]): T | undefined {\n if (array.length === 0) return undefined;\n return array[this.nextInt(0, array.length - 1)];\n }\n\n /**\n * Shuffles an array using the Fisher-Yates algorithm\n */\n shuffle<T>(array: T[]): T[] {\n const result = [...array];\n for (let i = result.length - 1; i > 0; i--) {\n const j = this.nextInt(0, i);\n const temp = result[i];\n result[i] = result[j] as T;\n result[j] = temp as T;\n }\n return result;\n }\n\n /**\n * Selects a random element based on weights\n */\n weightedPick<T>(items: WeightedItem<T>[]): T | undefined {\n if (items.length === 0) return undefined;\n\n const totalWeight = items.reduce((sum, item) => sum + item.weight, 0);\n let random = this.next() * totalWeight;\n\n for (const item of items) {\n random -= item.weight;\n if (random <= 0) {\n return item.item;\n }\n }\n\n return items[items.length - 1]?.item;\n }\n\n /**\n * Generates a random boolean value\n */\n nextBool(probability: number = 0.5): boolean {\n return this.chance(probability);\n }\n\n /**\n * Generates a random sign (-1 or 1)\n */\n nextSign(): -1 | 1 {\n return this.chance(0.5) ? 1 : -1;\n }\n\n /**\n * Generates a cryptographically secure random hexadecimal string\n * \n * This IS safe for:\n * - Session tokens\n * - API keys\n * - Reset tokens\n * - Any security-sensitive strings\n * \n * When seeded, always uses ISAAC for deterministic output.\n * \n * @param length - Number of bytes (each byte becomes 2 hex chars)\n */\n nextHex(length: number): string {\n const chars = '0123456789abcdef';\n const result = new Array(length * 2);\n \n // Always use ISAAC for deterministic behavior when seeded\n // crypto.getRandomValues would break determinism\n let idx = 0;\n for (let i = 0; i < length; i++) {\n const byte = this.rand() & 0xff;\n result[idx++] = chars[(byte >> 4) & 0x0f];\n result[idx++] = chars[byte & 0x0f];\n }\n return result.join('');\n }\n\n /**\n * Generates a cryptographically secure random byte array\n * \n * @param length - Number of random bytes to generate\n */\n nextBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n \n // Always use ISAAC for deterministic behavior when seeded\n // crypto.getRandomValues would break determinism\n for (let i = 0; i < length; i++) {\n bytes[i] = this.rand() & 0xff;\n }\n \n return bytes;\n }\n\n /**\n * Generates a cryptographically secure random Base64 string\n * \n * @param length - Number of random bytes before encoding\n */\n nextBase64(length: number): string {\n const bytes = this.nextBytes(length);\n const binary = new Array(bytes.length);\n for (let i = 0; i < bytes.length; i++) {\n binary[i] = String.fromCharCode(bytes[i] ?? 0);\n }\n return btoa(binary.join(''));\n }\n\n /**\n * Generates a random UUID v4 (cryptographically secure)\n * \n * Uses ISAAC for deterministic UUID generation when seeded.\n */\n nextUUID(): string {\n // Use ISAAC for deterministic UUID generation when seeded\n const bytes = new Uint8Array(16);\n for (let i = 0; i < 16; i++) {\n bytes[i] = this.rand() & 0xff;\n }\n \n // Set version (4) and variant (RFC 4122)\n const byte6 = bytes[6] ?? 0;\n const byte8 = bytes[8] ?? 0;\n bytes[6] = (byte6 & 0x0f) | 0x40;\n bytes[8] = (byte8 & 0x3f) | 0x80;\n \n const hex = Array.from(bytes).map(b => (b ?? 0).toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`;\n }\n\n /**\n * Creates a new SecureSeededRNG with a random seed derived from this one\n */\n fork(): SecureSeededRNG {\n return new SecureSeededRNG(this.nextInt(0, 4294967295));\n }\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Creates a new SeededRNG instance (fast, NOT cryptographically secure)\n * \n * This is a convenience factory function that creates a new SeededRNG instance.\n * The SeededRNG uses a Linear Congruential Generator (LCG) algorithm which is\n * fast but NOT suitable for security-sensitive operations.\n * \n * @param seed - Optional seed value. If not provided, a random seed will be generated.\n * Pass `null` to explicitly indicate no seed is provided.\n * @returns A new SeededRNG instance initialized with the provided or generated seed\n * \n * @example\n * ```typescript\n * // With a specific seed (reproducible sequences)\n * const rng = createRNG(42);\n * console.log(rng.nextInt(1, 100)); // Always returns the same value\n * \n * // Without seed (random each time)\n * const rng2 = createRNG();\n * ```\n * \n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random|Math.random}\n * @group Seeded RNG\n * @since 0.1.0\n */\nexport function createRNG(seed?: number | null): SeededRNG {\n return new SeededRNG(seed ?? undefined);\n}\n\n/**\n * Creates a new SecureSeededRNG instance (cryptographically secure)\n * \n * This is a convenience factory function that creates a new SecureSeededRNG instance.\n * The SecureSeededRNG uses the ISAAC cipher algorithm which is cryptographically\n * secure and suitable for security-sensitive operations like password generation,\n * token creation, and cryptographic key derivation.\n * \n * @param seed - Optional seed value for deterministic sequences.\n * If not provided, a cryptographically random seed will be generated\n * using `crypto.getRandomValues()` where available.\n * Pass `null` to explicitly indicate no seed is provided.\n * @returns A new SecureSeededRNG instance initialized with the provided or generated seed\n * \n * @example\n * ```typescript\n * // With a specific seed (reproducible sequences)\n * const rng = createSecureRNG(42);\n * console.log(rng.nextHex(16)); // Always returns the same value\n * \n * // Without seed (cryptographically random each time)\n * const rng2 = createSecureRNG();\n * const password = rng2.nextHex(32); // 32-byte secure password\n * ```\n * \n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues|crypto.getRandomValues}\n * @group Secure RNG\n * @since 0.1.0\n */\nexport function createSecureRNG(seed?: number | null): SecureSeededRNG {\n return new SecureSeededRNG(seed ?? undefined);\n}\n\n/**\n * Generates a single random integer with a seed (one-shot, NOT secure)\n * \n * Creates a temporary SeededRNG instance, generates a single random integer\n * in the specified range [min, max], and returns the result.\n * \n * ⚠️ This is NOT cryptographically secure. Use for games, testing, or\n * non-security-related randomness only.\n * \n * @param seed - The seed value for deterministic randomness\n * @param min - Minimum value (inclusive)\n * @param max - Maximum value (inclusive)\n * @returns A random integer between min and max (inclusive)\n * \n * @example\n * ```typescript\n * // Always returns the same value for the same seed\n * console.log(seededInt(12345, 1, 100)); // Always returns 38 (for example)\n * ```\n * \n * @see {@link SeededRNG.nextInt}\n * @since 0.1.0\n */\nexport function seededInt(seed: number, min: number, max: number): number {\n const rng = new SeededRNG(seed);\n return rng.nextInt(min, max);\n}\n\n/**\n * Generates a single random float with a seed (one-shot, NOT secure)\n * \n * Creates a temporary SeededRNG instance, generates a single random float\n * in the specified range [min, max), and returns the result.\n * \n * ⚠️ This is NOT cryptographically secure. Use for games, testing, or\n * non-security-related randomness only.\n * \n * @param seed - The seed value for deterministic randomness\n * @param min - Minimum value (inclusive)\n * @param max - Maximum value (exclusive)\n * @returns A random float between min (inclusive) and max (exclusive)\n * \n * @example\n * ```typescript\n * // Always returns the same value for the same seed\n * console.log(seededFloat(12345, 0.0, 1.0)); // Always returns 0.83... (for example)\n * ```\n * \n * @see {@link SeededRNG.nextFloat}\n * @since 0.1.0\n */\nexport function seededFloat(seed: number, min: number, max: number): number {\n const rng = new SeededRNG(seed);\n return rng.nextFloat(min, max);\n}\n\n/**\n * Shuffles an array with a seed (one-shot, NOT secure)\n * \n * Creates a temporary SeededRNG instance, shuffles the array using the\n * Fisher-Yates algorithm with the seeded random number generator, and\n * returns a new shuffled array.\n * \n * ⚠️ This is NOT cryptographically secure. Use for games, testing, or\n * non-security-related randomness only.\n * \n * @param seed - The seed value for deterministic shuffling\n * @param array - The array to shuffle\n * @returns A new array with elements in random order (deterministic based on seed)\n * \n * @example\n * ```typescript\n * // Always produces the same shuffle for the same seed\n * const result = seededShuffle(42, ['a', 'b', 'c', 'd']);\n * // Result is always: ['c', 'a', 'd', 'b'] (for example)\n * ```\n * \n * @see {@link SeededRNG.shuffle}\n * @since 0.1.0\n */\nexport function seededShuffle<T>(seed: number, array: T[]): T[] {\n const rng = new SeededRNG(seed);\n return rng.shuffle(array);\n}\n\n/**\n * Picks a random element with a seed (one-shot, NOT secure)\n * \n * Creates a temporary SeededRNG instance and selects a random element\n * from the provided array.\n * \n * ⚠️ This is NOT cryptographically secure. Use for games, testing, or\n * non-security-related randomness only.\n * \n * @param seed - The seed value for deterministic selection\n * @param array - The array to pick from\n * @returns A randomly selected element from the array, or undefined if empty\n * \n * @example\n * ```typescript\n * // Always picks the same element for the same seed\n * const item = seededPick(42, ['apple', 'banana', 'cherry']);\n * // Always returns 'banana' (for example)\n * \n * // Returns undefined for empty arrays\n * const empty = seededPick(1, []); // Returns undefined\n * ```\n * \n * @see {@link SeededRNG.pick}\n * @since 0.1.0\n */\nexport function seededPick<T>(seed: number, array: T[]): T | undefined {\n const rng = new SeededRNG(seed);\n return rng.pick(array);\n}\n\n/**\n * Generates a single cryptographically secure random integer with a seed\n * \n * Creates a temporary SecureSeededRNG instance and generates a single\n * random integer in the specified range [min, max].\n * \n * This IS cryptographically secure and suitable for security-sensitive\n * operations like generating random IDs, tokens, or any value that\n * should not be predictable.\n * \n * @param seed - The seed value for deterministic (but still secure) sequences\n * @param min - Minimum value (inclusive)\n * @param max - Maximum value (inclusive)\n * @returns A cryptographically secure random integer between min and max (inclusive)\n * \n * @example\n * ```typescript\n * // Generates a secure random number (still deterministic with same seed)\n * const num = seededSecureInt(42, 1, 1000000);\n * ```\n * \n * @see {@link SecureSeededRNG.nextInt}\n * @since 0.1.0\n */\nexport function seededSecureInt(seed: number, min: number, max: number): number {\n const rng = new SecureSeededRNG(seed);\n return rng.nextInt(min, max);\n}\n\n/**\n * Generates a cryptographically secure random hex string (seeded)\n * \n * Creates a temporary SecureSeededRNG instance and generates a\n * cryptographically secure hexadecimal string.\n * \n * This IS safe for:\n * - Session tokens\n * - API keys\n * - Password reset tokens\n * - Any security-sensitive strings\n * \n * @param seed - The seed value for deterministic (but still secure) sequences\n * @param length - Number of bytes (each byte becomes 2 hex characters)\n * @returns A cryptographically secure hexadecimal string\n * \n * @example\n * ```typescript\n * // Generate a 32-byte (64 character) secure hex string\n * const token = seededSecureHex(42, 32);\n * // Returns: 'a1b2c3d4e5f6...'\n * \n * // Generate a 16-byte API key\n * const apiKey = seededSecureHex(Date.now(), 16);\n * ```\n * \n * @see {@link SecureSeededRNG.nextHex}\n * @since 0.1.0\n */\nexport function seededSecureHex(seed: number, length: number): string {\n const rng = new SecureSeededRNG(seed);\n return rng.nextHex(length);\n}\n\nexport { SeededRNG as default };\n"]}