Home › Random Number Generator

Random Number Generator

UtilityRuns in your browserNothing uploaded

Generate random numbers

Where these numbers come from

This tool uses crypto.getRandomValues(), the browser's cryptographically secure random number generator, which draws entropy from the operating system — hardware sources, timing jitter, and other unpredictable inputs.

That is a meaningful difference from Math.random(), which most random generators use. Math.random() is a pseudo-random generator: fast, statistically reasonable, and entirely predictable to anyone who can observe enough output. It is fine for animations and shuffling a playlist, and unsuitable for anything where predictability matters.

Pseudo-random versus truly random

A pseudo-random generator is a deterministic algorithm. Given the same starting seed it produces exactly the same sequence forever. This is genuinely useful — reproducible simulations and repeatable tests depend on it — but the sequence is predictable once the seed is known.

A cryptographically secure generator is also algorithmic but is seeded from genuine environmental entropy and designed so that observing past output tells you nothing about future output.

True random generators sample physical processes — radioactive decay, thermal noise, atmospheric noise. These are slower and generally reserved for seeding other generators or for applications where the provenance must be demonstrable.

For anything involving security, money, or fairness, cryptographic randomness is the minimum standard.

Modulo bias, a subtle and common bug

The obvious way to get a number in a range is random_value % range. This introduces a real statistical bias.

Suppose your generator returns 0–255 and you want 0–9. Taking modulo 10 maps 256 values onto 10 buckets. Since 256 is not divisible by 10, the values 0–5 receive 26 source values each while 6–9 receive only 25. The low numbers come up about 4% more often.

The bias is small here and grows as the range approaches the generator's size. In a lottery, a card shuffle, or a cryptographic nonce, it is exploitable.

The correct fix is rejection sampling: discard values that fall in the uneven tail and draw again. This tool does that, so the distribution is genuinely uniform.

Shuffling correctly

Generating unique values is closely related to shuffling, and shuffling has its own well-known trap.

The common approach — array.sort(() => Math.random() - 0.5) — is broken. Sort algorithms assume a consistent comparison function, and a random comparator violates that. The result is a non-uniform distribution where some permutations are far more likely than others, and the exact bias depends on the engine's sort implementation.

The correct algorithm is the Fisher-Yates shuffle: iterate from the last element backwards, swapping each with a randomly chosen element at or before its position. It is O(n), simple to implement, and produces a genuinely uniform permutation.

Where randomness quality actually matters

For UI animations, non-critical shuffling, and visual effects, Math.random() is entirely appropriate and faster. The distinction is whether an adversary or a statistician would care.

Frequently asked questions

Is Math.random() secure?

No. It is a pseudo-random generator that is predictable to anyone who observes enough output. Use crypto.getRandomValues for tokens, keys, passwords, or anything where predictability matters.

What is modulo bias?

Using the modulo operator to fit random values into a range makes some values slightly more likely when the range does not divide evenly into the generator's output space. Rejection sampling eliminates it.

Why is array.sort with a random comparator wrong for shuffling?

Sort algorithms assume a consistent comparison function. A random comparator violates that, producing a non-uniform distribution that depends on the engine's implementation. Use Fisher-Yates instead.

What is the difference between pseudo-random and truly random?

Pseudo-random is deterministic from a seed and reproduces the same sequence. Cryptographically secure generators are seeded from environmental entropy and designed so past output reveals nothing about future output.