How do random number generators work?

Most random number generators are formulas: they start from a value called a seed and apply the same calculation again and again to produce a sequence that looks random but is fully determined by that seed. Cryptographically secure generators add unpredictable input collected by the operating system, such as hardware timing noise, so their output cannot be predicted even by someone who has seen earlier numbers. Turning those raw numbers into a fair "1 to 6" or "1 to 100" needs one more careful step, which is where many simple programs go wrong.

6 min read

The short answer

A computer follows instructions exactly, so it cannot invent randomness out of nothing. It either computes numbers that pass statistical tests for randomness (a pseudo random number generator, PRNG), or it measures something physically unpredictable and processes it (a true or hardware random source). Modern systems combine the two: the operating system gathers unpredictable noise and uses it to seed a cryptographically secure PRNG (CSPRNG), which then produces as many numbers as needed.

The generator on this page uses the browser's secure source through the Web Crypto API and converts it to your range without bias. Enter a Minimum and Maximum, choose How many, and press Generate.

Try it here: Random Number Generator

Open the full tool page

Pseudo random generators and seeds

A PRNG keeps an internal state. Each time you ask for a number, it scrambles the state with a fixed formula and outputs part of the result. The simplest classic design, the linear congruential generator, computes the next state as (a times state plus c) modulo m. Better designs such as the Mersenne Twister (the default in Python's random module) or the xorshift family produce much higher quality sequences, and the Mersenne Twister only repeats after 2 to the power 19,937 minus 1 steps.

The seed is the starting state. The same seed always produces the same sequence. That is a feature, not a flaw, in many situations: a scientist can rerun a simulation exactly, a game can rebuild a world from a short seed code, and a test can reproduce a bug. If a program seeds from something guessable such as the current time in seconds, though, an attacker can try every likely seed and recreate the numbers.

Pseudo random vs cryptographically secure

Fast general purpose PRNGs are statistically good but predictable: after observing enough outputs, it is possible to reconstruct the internal state and predict every following number. That is fine for a particle effect in a game, not fine for a password, a lottery or a security token.

TypeWhere the numbers come fromPredictable?Typical use
Simple PRNG (LCG, xorshift, Mersenne Twister)A formula and a seedYes, from the seed or enough outputsSimulations, games, graphics
CSPRNGA formula seeded and refreshed with system noiseNo, not in practicePasswords, keys, draws, tokens
Hardware RNGPhysical noise such as thermal or timing jitterNoFeeding the operating system's pool

Where computers find real randomness

Operating systems collect small unpredictable events: the exact timing of interrupts, disk and network activity, and dedicated hardware generators built into many modern processors that sample electrical noise. This entropy is mixed into a pool and used to seed and regularly reseed a CSPRNG. Linux exposes it through getrandom and /dev/urandom, and Windows through its system cryptography functions.

Some services go further for publicity or extra assurance. Random.org uses atmospheric radio noise, and Cloudflare famously films a wall of lava lamps as one of its entropy sources. For everyday needs, the operating system's generator is already strong enough for encryption keys.

How browsers generate secure random numbers

JavaScript has two options. Math.random() returns a number between 0 and 1 from a fast PRNG (current engines use xorshift style algorithms). It is fine for animations but is not designed to be unpredictable, and the specification makes no security promise.

crypto.getRandomValues() fills an array with random bytes from the browser's CSPRNG, which is seeded by the operating system. It is available in every modern browser, works offline, and is what password generators and key generation code should use. A single call can return at most 65,536 bytes, so large jobs call it repeatedly. This generator, like the coin flip, dice roller, wheel and name picker on Anyfeat, uses crypto.getRandomValues.

Why rand() % n can be biased

A generator gives you raw values in a fixed range, for example a byte from 0 to 255. The obvious way to get a number from 0 to 5 is to take the remainder after dividing by 6 (value % 6). The problem: 256 values do not divide evenly into 6 groups. 256 is 42 times 6 plus 4, so the remainders 0 to 3 occur 43 times each and the remainders 4 and 5 only 42 times. Some results are about 2.4% more likely than others. This is called modulo bias.

With 32 bit values and a small range the bias becomes tiny, but with large ranges it grows. The standard fix is rejection sampling: find the largest multiple of n that fits in the raw range (252 in the byte example), throw away any raw value at or above it and draw again. Every remaining value maps onto the range evenly. This generator draws 32 bit values and rejects the uneven tail, so each number in your range has exactly the same probability.

A similar mistake is Math.floor(Math.random() * n) for security purposes. The rounding is fine for most ranges, but the source is predictable, so it should not be used for passwords or draws with money at stake.

Unique numbers, shuffles and common pitfalls

  • Unique numbers: to draw without repeats, shuffle the full range with the Fisher Yates algorithm and take the first k, or draw and discard repeats. This generator does exactly that when No repeats is ticked, and tells you if the range is too small for the count.
  • Biased shuffles: sorting a list with a random comparison function does not give a uniform shuffle. Use Fisher Yates.
  • Reseeding too often: seeding a PRNG with the time in a loop can produce the same number many times in a row.
  • Decimals: picking a random decimal by scaling a random fraction can make the end points less likely. This tool instead draws a whole number of steps (for 2 decimals, hundredths) so both ends are included with equal chance.
  • Expecting patterns to be absent: real random output contains streaks and repeats. Seeing 7 twice in a row is not a sign of a broken generator.

Step by step

  1. Set the rangeEnter the Minimum and Maximum. Both numbers are included.
  2. Choose how manySet How many (1 to 10,000) and tick No repeats if every number must be different.
  3. Pick the formatChoose Whole numbers or up to 4 decimals, and tick Sort if you want the result in order.
  4. Generate and copyPress Generate, Enter or the space bar, then use Copy to take the numbers.

Frequently asked questions

Are computer random numbers truly random?

Not in the physical sense: a PRNG is a formula. But a cryptographically secure generator seeded with hardware noise is unpredictable in practice, which is what matters for draws, games and passwords.

What is a seed in a random number generator?

The starting value of the generator's internal state. The same seed always produces the same sequence, which is useful for reproducible simulations and dangerous if an attacker can guess it.

Is Math.random() safe for passwords?

No. It is fast but predictable. Use crypto.getRandomValues() in the browser, or your platform's secure random function elsewhere.

Is this random number generator fair?

Yes. It uses crypto.getRandomValues and rejection sampling, so every number in the range has exactly the same chance, with no modulo bias.

Does the generator send my numbers to a server?

No. Everything runs in your browser and works offline once the page is loaded. Nothing you generate is stored on a server.

Why did I get the same number twice?

Repeats are a normal part of randomness. In the range 1 to 10 the chance that the next number equals the previous one is 10%. Tick No repeats if you need all numbers to be different.