Seeded Random Number Generator
Seedrandom is a JavaScript library that provides seeded pseudorandom number generators (PRNGs). It allows developers to create reproducible sequences of 'random' numbers, which is crucial for deterministic simulations, testing, and specific cryptographic applications (though caution is advised for security-sensitive contexts due to common misuse patterns). The current stable version is 3.0.5, released in late 2019, suggesting a mature but slow-moving maintenance cadence. Key differentiators include its ability to replace the global `Math.random` for debugging or testing purposes, and its inclusion of various PRNG algorithms (such as ARC4, Alea, xor128, Tyche-i) offering different performance characteristics and period lengths. It supports use in web browsers via script tags, as a Node.js module, and as an AMD module. Developers can instantiate independent PRNGs or opt to globally override `Math.random` with a seeded sequence.
Common errors
-
My application's 'random' numbers are predictable or always the same across runs.
cause A third-party library or your own code inadvertently called `seedrandom('some_seed')` without `new`, which globally overwrote `Math.random` with a deterministic sequence.fixAudit your codebase and all dependencies for calls to `seedrandom()` or `Math.seedrandom()` that are not explicitly creating a new instance (e.g., `new seedrandom('seed')`). If `Math.random` must be overridden for testing, ensure it is restored to its original value after the test, especially in production environments. -
TypeError: Cannot read properties of undefined (reading 'double') or similar when trying to use specialized PRNGs like Alea.
cause This usually indicates an incorrect import or instantiation of a specific PRNG algorithm (e.g., `alea`). You might be trying to access methods on an undefined object or one not correctly initialized.fixEnsure you are importing the specific algorithm correctly, for example, `import Alea from 'seedrandom/lib/alea';`. Then, instantiate it as a new object: `const arng = new Alea('your-seed');`.
Warnings
- breaking Calling `seedrandom('seed_string')` or `Math.seedrandom('seed_string')` (when `seedrandom` is globally loaded via a script tag) without `new` or without explicitly assigning the return value to a local variable will permanently override the global `Math.random()` function. While useful for deterministic testing, this is a critical security vulnerability if done inadvertently in a production library or security-sensitive application, making `Math.random` completely predictable.
- gotcha The faster PRNG algorithms provided within the `lib/` directory (e.g., `alea`, `xor128`, `tychei`) do not include autoseeding capabilities. If you need robust, less predictable initial seeds for these algorithms in a production environment, you must generate them separately or use the main `seedrandom` function (which can autoseed) to generate a strong seed for them.
- gotcha Documentation and older examples may show `new Math.seedrandom()` for instantiation. While this works in global script contexts, for modern module-based environments (Node.js, bundlers), it's cleaner and more direct to import the `seedrandom` function directly and use `new seedrandom()` or `seedrandom('seed', { state: true })` for creating instances.
Install
-
npm install seedrandom -
yarn add seedrandom -
pnpm add seedrandom
Imports
- seedrandom
import { seedrandom } from 'seedrandom'; // Incorrectly assumes named export for main functionimport seedrandom from 'seedrandom';
- seedrandom (CommonJS)
const { seedrandom } = require('seedrandom'); // Incorrect, main function is default/module.exportsconst seedrandom = require('seedrandom'); - Alea (Algorithm)
import { alea } from 'seedrandom'; // Alea is not a named export from the main packageimport Alea from 'seedrandom/lib/alea';
Quickstart
import seedrandom from 'seedrandom';
// Create an independent, seeded PRNG instance
const myrng = new seedrandom('my-secret-seed');
console.log('Seeded PRNG instance results (ARC4):');
console.log(myrng()); // Always the same for this seed
console.log(myrng()); // Always the same subsequent value
// Demonstrating other PRNGs (Alea algorithm)
import Alea from 'seedrandom/lib/alea';
const aleaRng = new Alea('another-seed'); // Alea requires an explicit seed
console.log('\nSeeded PRNG instance results (Alea):');
console.log(aleaRng());
console.log(aleaRng.double()); // Alea can provide 56 bits of randomness
// --- WARNING: Global Math.random override example ---
// This directly modifies the global Math.random, making it predictable.
// This should only be used for controlled testing and must be restored.
console.log('\nGlobal Math.random override (WARNING!):');
const originalMathRandom = Math.random; // Save original Math.random
seedrandom('global-override-seed'); // Calling without 'new' or assignment overrides Math.random
console.log(Math.random());
console.log(Math.random());
// Restore original Math.random after demonstration to prevent side effects
Math.random = originalMathRandom;
console.log('\nMath.random restored to original behavior.');