Randomness in JavaScript — Why Math.random() Isn't Random Enough

Building a fair lottery picker requires more than Math.random(). Here's the difference between pseudo-random and cryptographically secure random, and when it matters.

Math.random() — Fast but Predictable

Math.random(); // 0.7234... 

This uses a PRNG (pseudo-random number generator) — typically xorshift128+ in V8. It's fast but deterministic: given the same seed, the sequence is reproducible.

For games and UI animations, this is fine. For lottery picks and security tokens, it isn't.

crypto.getRandomValues() — Truly Random

function secureRandom() { const array = new Uint32Array(1); crypto.getRandomValues(array); return array[0] / (0xFFFFFFFF + 1); // 0 to 1 } 

This uses the OS entropy pool (hardware events, timing jitter) — genuinely unpredictable.

Fair Shuffle (Fisher-Yates)

The naive shuffle (sort(() => Math.random() - 0.5)) is biased. Use Fisher-Yates:

function fairShuffle(array) { const arr = [...array]; for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(secureRandom() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } return arr; } 

Drawing Without Replacement

function drawWithoutReplacement(items, count) { if (count > items.length) throw new Error('Cannot draw more than available'); return fairShuffle(items).slice(0, count); } 

Drawing With Replacement

function drawWithReplacement(items, count) { return Array.from({ length: count }, () => { const index = Math.floor(secureRandom() * items.length); return items[index]; }); } 

Random Number in Range (Without Modulo Bias)

Simple modulo creates bias because the range rarely divides evenly into the max integer:

function secureRandomInt(min, max) { const range = max - min + 1; const maxValid = Math.floor(0x100000000 / range) * range; let value; do { const arr = new Uint32Array(1); crypto.getRandomValues(arr); value = arr[0]; } while (value >= maxValid); // Reject values in the biased range return min + (value % range); } 

Try the random picker at toolzip.app/tools/random-picker.