Math.random is not random. It is a deterministic algorithm that produces numbers that look random but are entirely predictable if you know the seed. For most applications this is fine. For security it is catastrophic.
Pseudorandom vs. cryptographically secure
Math.random() uses a pseudorandom number generator (PRNG). It is fast and produces a uniform distribution, but the sequence is deterministic. Given the same seed, it produces the same sequence every time.
// Pseudorandom - fine for games, simulations, UI
Math.random(); // 0.0 to 1.0
// Cryptographically secure - required for security
crypto.getRandomValues(new Uint32Array(1))[0];
crypto.getRandomValues() uses the operating system's cryptographic random source (like /dev/urandom on Linux). It is slower but unpredictable, making it suitable for generating passwords, tokens, and encryption keys.
Generating random integers in a range
The naive approach has a subtle bias:
// Biased - do not use for anything important
Math.floor(Math.random() * (max - min + 1)) + min;
The bias comes from the fact that Math.random() produces a 64-bit float, and the modulo operation (Math.floor(... * range)) does not distribute evenly when the range is not a power of 2.
For unbiased random integers:
function secureRandomInt(min, max) {
const range = max - min + 1;
const bytesNeeded = Math.ceil(Math.log2(range) / 8);
const maxValid = Math.floor(256 ** bytesNeeded / range) * range;
let value;
do {
const bytes = crypto.getRandomValues(new Uint8Array(bytesNeeded));
value = bytes.reduce((acc, b, i) => acc + b * (256 ** i), 0);
} while (value >= maxValid);
return min + (value % range);
}
The rejection sampling (while (value >= maxValid)) eliminates the modulo bias entirely.
Common use cases
-
Passwords: Use
crypto.getRandomValueswith a character set -
UUIDs: Use
crypto.randomUUID()(v4) - Shuffling: Fisher-Yates shuffle with random swaps
- Sampling: Random selection from a dataset
- Testing: Generating test data with known distributions
For generating random numbers with various distributions and ranges, I built a generator at zovo.one/free-tools/number-generator. It supports integers, decimals, custom ranges, and batch generation.
I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.
Top comments (0)