@opensourceframework/seeded-rng
Advanced tools
+4
-5
| { | ||
| "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" |
-542
| '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"]} |
-558
| /** | ||
| * 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 }; |
-558
| /** | ||
| * 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 }; |
-528
| /** | ||
| * @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"]} |
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
15655
-90.29%4
-60%0
-100%1
Infinity%2
100%2
100%