Random Number Generator
PRNG vs CSPRNG: The One Thing to Know
The difference between a pseudo-random number generator and a cryptographically secure one is the difference between Math.random() and crypto.getRandomValues(). Use the wrong one in a security context and your reset tokens become predictable.
This tool defaults to a PRNG (seeded, for test reproducibility). Toggle CSPRNG for anything security-sensitive.
The Two Types You Need
PRNG (Pseudo-Random Number Generator)
Deterministic given a seed. Same seed -> same sequence. Essential for:
- Reproducible unit tests
- Seeded procedural world generation
- Debugging "random" failures
Default uses Mulberry32 (fast, decent quality for tests).
CSPRNG (Cryptographically Secure PRNG)
Draws from the OS entropy pool -- truly unpredictable. Required for:
- Password reset tokens
- Session identifiers, API keys, nonce values
- Anything that protects a user account
Use crypto.getRandomValues(new Uint8Array(32)) in browsers.
Why This Matters: A War Story
A shipped project once used Math.random() to generate password reset tokens. Looks secure until you realize Math.random() in V8 is xorshift128+ with only 128 bits of state. An attacker capturing two consecutive outputs can reconstruct the state and predict every subsequent token. Fix: one-line swap to crypto.getRandomValues.
How to Use
Set min/max, quantity, type (integer, float, UUID, dice). Toggle Allow Duplicates off for lottery draws. Set seed for reproducibility.
Dice: 1d20 = one 20-sided die. 2d6+3 = two d6 + 3. 4dF = Fudge notation.
UUID v4: 122 random bits. 50% collision probability after ~2.71e18 UUIDs. You won't collide in practice.
Uniform Distribution and Modulo Bias
A naive implementation that takes a random byte and returns it modulo N has 'modulo bias' -- values in the remainder of 256 mod N land unevenly. The tool mitigates this via rejection sampling. For large ranges (BigInt) it avoids precision loss.
When to Use a Seed
Seed for: unit tests (flaky usually means non-seeded), procedural worlds, reproducing failures. Don't seed for: security flows, anything unpredictable.
Practical Examples
Random element. index = floor(rand() * arr.length). Standard for sweepstakes. Reproducible data. Same seed today and tomorrow gives identical output. CI becomes deterministic. A/B bucketing. 1-100 per session. 1-50 = A, 51-100 = B. Converges at scale. Playlist shuffle. No-repeats + N = Fisher-Yates without writing it.
FAQ
Q: Truly random? A: PRNG is deterministic given seed. OS entropy via CSPRNG. Use CSPRNG for security. Q: Huge ranges? A: BigInt sampling handles billions of values. Q: UUID v1/v5? A: Only v4. Time-based UUIDs need a library. Q: Batch limit? A: 10,000. More risks browser RAM. Q: No-repeats? A: Partial Fisher-Yates. Faster than retrying.