True random and pseudo-random numbers
A computer can measure a physical process or compute numbers from a secret starting value. Most randomness you meet comes from the second method, fed by the first.
Published 10 October 2026
There are two ways to get random numbers out of a computer. One is to measure something physical that nobody can predict, such as electrical noise. The other is to run an algorithm that turns a starting value, the seed, into a long stream of numbers that look random. NIST’s standard for random bit generators calls the first kind non-deterministic and the second deterministic, and notes in a footnote that they are also known as true random and pseudo-random generators.
The practical question is rarely which kind is “really” random. It is whether anyone could predict the next number, and the answer depends far more on the seed and the algorithm than on the label.
Physical sources
A physical random number generator samples a process whose outcome can’t be computed in advance. RANDOM.ORG, a long-running public service, uses atmospheric noise picked up by radio receivers and turns small variations in its amplitude into numbers. Its own introduction to randomness sums up the trade-off: physical generators are non-deterministic and have no period, so their output never settles into a repeating cycle, but they are slow compared with algorithms.
Cloudflare’s LavaRand is a better-known example. A camera points at a wall of lava lamps in the lobby of the company’s San Francisco office, and the video feed is mixed into a cryptographic generator. Cloudflare describes it as a secondary source: production servers mix its output with their own local entropy and write the result into the Linux kernel’s generator, so the lamps add unpredictability without anything depending on them alone. The design point is that mixing works in the defender’s favour. As long as one input stays unpredictable, the mixed output does too.
Pseudo-random generators and seeds
A pseudo-random number generator (PRNG) is a deterministic algorithm. Give it the same seed and it produces the same sequence every time, which is exactly what a scientist re-running a simulation or a game developer replaying a level wants. Every PRNG also has a finite period, after which the sequence repeats, although good modern ones have periods far longer than anyone will use.
The weakness is the seed. If a program seeds its generator with a 32-bit number, there are only 4,294,967,296 possible sequences, however good the algorithm. If it seeds from the clock, an attacker who can guess the time narrows that much further. The best-known failure of this kind, an online poker site whose shuffles could be predicted from the server clock in 1999, is described in the guide to fair shuffling.
Cryptographic generators and the operating system
A cryptographically secure PRNG is designed so that seeing its output doesn’t help predict what comes next, provided its seed has enough entropy and stays secret. NIST SP 800-90A puts it directly: if the seed is kept secret and the algorithm is well designed, the output bits are unpredictable up to the generator’s security strength. The approved mechanisms are built on hash functions and block ciphers (Hash_DRBG, HMAC_DRBG and CTR_DRBG). The 2015 revision also removed one former mechanism, Dual_EC_DRBG.
Operating systems combine the two approaches. The Linux kernel, for example, gathers entropy from device drivers and other sources of environmental noise and uses it to seed a cryptographically secure generator; the random(7) manual recommends that most programs read from /dev/urandom or call getrandom(). Hardware noise is used where it is strong, at the start, and a fast algorithm does the bulk of the work.
| Kind | How it works | Repeatable | Typical use |
|---|---|---|---|
| Physical (true random) | Measures noise, radioactive decay, lava lamps and similar | No | Seeding other generators, public draws |
| Ordinary PRNG | Algorithm from a seed, tuned for speed and statistical quality | Yes, from the seed | Simulations, games, tests |
| Cryptographic PRNG | Algorithm built on hashes or ciphers, seeded from the operating system’s entropy | Not in practice: the seed is secret and refreshed | Keys, passwords, tokens, fair draws |
What the NIST standards cover
The US National Institute of Standards and Technology publishes the reference specifications that much of the industry builds and tests against. They split the problem into parts.
| Publication | What it specifies |
|---|---|
| SP 800-90A Rev. 1 (2015) | Deterministic random bit generators: the algorithms that stretch a seed into output |
| SP 800-90B (2018) | Entropy sources: how to design them, estimate their min-entropy and health-test them |
| SP 800-90C (2025) | Constructions that combine an entropy source with a deterministic generator into a complete random bit generator |
| SP 800-22 Rev. 1a (2010) | A suite of statistical tests for binary sequences from random and pseudo-random generators |
SP 800-22’s suite has 15 tests, starting with the simplest, a count of ones against zeros (the frequency or monobit test), and running through runs, block patterns, spectral and complexity tests. The document is careful about what passing means: no set of statistical tests can certify a generator as fit for a particular use, and statistical testing is no substitute for cryptanalysis. A generator can pass every test and still be predictable to someone who knows its seed. NIST announced in 2022 that it would revise SP 800-22.
Math.random and crypto.getRandomValues
Web browsers offer two generators, and the difference between them is the difference described above.
Math.random() returns a decimal from 0 up to but not including 1. The browser chooses the seed, and the page can’t set or reset it. MDN’s reference states plainly that it does not provide cryptographically secure numbers and should not be used for anything security-related. Chrome’s engine, V8, has used an algorithm called xorshift128+ since late 2015, replacing an older one that could produce only 2³² different values; the V8 team’s own write-up notes that the new one is still not cryptographically secure.
crypto.getRandomValues(), from the W3C Web Cryptography API, fills an array of integers with random values. The specification asks browsers to use a well-established cryptographic PRNG seeded with high-quality entropy, such as from an operating-system source like /dev/urandom, rather than reading the hardware source directly; MDN notes that implementations do this for performance. A single call can return at most 65,536 bytes. For generating encryption keys the specification points to generateKey() instead, but for passwords, tokens and draws getRandomValues() is the standard tool.
What this site uses
Every tool on this site, from the random number generator to the password generator and the UUID generator, draws from crypto.getRandomValues() in your browser. Nothing uses Math.random(). The random bits are turned into a number in your range by rejection sampling, which keeps every value exactly equally likely; the guide to modulo bias shows why that step matters.
Strictly, that makes the output pseudo-random: it comes from an algorithm. In practice it is unpredictable, because the algorithm is a cryptographic one and its seed comes from the operating system’s entropy pool, which nobody outside your device can see. It also means a draw can’t be repeated on request. There is no seed to type in, and that is deliberate. If you need a sequence you can reproduce, for testing or research, use a seeded generator in a programming language and record the seed.
Sources
- NIST SP 800-90A Rev. 1, Recommendation for Random Number Generation Using Deterministic Random Bit Generators (June 2015)
- NIST SP 800-90B, Recommendation for the Entropy Sources Used for Random Bit Generation (January 2018)
- NIST SP 800-90C, Recommendation for Random Bit Generator (RBG) Constructions (September 2025)
- NIST SP 800-22 Rev. 1a, A Statistical Test Suite for Random and Pseudorandom Number Generators for Cryptographic Applications (April 2010)
- W3C, Web Cryptography API: getRandomValues()
- MDN, Math.random()
- MDN, Crypto: getRandomValues() method
- V8 blog, There’s Math.random(), and then there’s Math.random() (2015)
- Linux man-pages, random(7): overview of interfaces for obtaining randomness
- RANDOM.ORG, Introduction to randomness and random numbers
- Cloudflare blog, LavaRand in production: the nitty-gritty technical details (November 2017)
- Cloudflare blog, Randomness 101: LavaRand in production