The Complete Guide to Random Number Generation: Algorithms, Security, and Real-World Applications
A comprehensive guide to random number generation covering the differences between true and pseudo-random numbers, common algorithms (LCG, Mersenne Twister, Xorshift), cryptographic security (CSPRNG), and practical applications in gaming, cryptography, Monte Carlo simulations, and more.
Random numbers are everywhere in computer science, cryptography, statistics, and everyday life. From dice simulations in games to key generation in cryptography, from Monte Carlo simulations in scientific research to online lottery draws, random numbers play a critical role. Yet the concept of “randomness” is far more complex than it appears on the surface — computers are fundamentally deterministic machines, so how can they produce “random” numbers? This article takes you on a deep dive into every aspect of random number generation.
Need to generate random numbers quickly? Try our Random Number Generator, with support for custom ranges, batch generation, and more.
1. What Are Random Numbers?
A random number is a value that appears within a certain range according to some probability distribution, and cannot be precisely predicted. In an ideal random number generation process, each result should be independent, and every value within the given range should have an equal probability of being selected (for uniform distributions).
Core Properties of Random Numbers
| Property | Description |
|---|---|
| Unpredictability | Cannot infer the next number from previously generated numbers |
| Uniform Distribution | Each value has an equal probability of being selected (for uniform random numbers) |
| Independence | Each generation result does not affect others |
| Non-repeatability | Ideally, the sequence should not exhibit periodic repetition |
The Two Major Types of Random Numbers
In computer science, random numbers fall into two categories:
- True Random Numbers (TRN): Generated from physical phenomena (such as electronic noise, radioactive decay, atmospheric noise, etc.), possessing genuine unpredictability.
- Pseudo-Random Numbers (PRN): Sequences produced by mathematical algorithms through deterministic processes that exhibit statistical randomness but are essentially reproducible.
2. True Random Numbers vs. Pseudo-Random Numbers
2.1 True Random Numbers (TRNG)
True Random Number Generators (TRNGs) harness random phenomena from the physical world to produce values.
Common Physical Random Sources:
| Source | How It Works | Use Cases |
|---|---|---|
| Electronic Thermal Noise | Electron movement fluctuations caused by temperature in circuits | Hardware security modules |
| Radioactive Decay | Unpredictable time intervals of atomic nucleus decay | Scientific research |
| Atmospheric Noise | Electromagnetic interference from lightning and atmospheric activity | random.org |
| Photon Quantum States | Leveraging intrinsic quantum mechanics randomness | Quantum random number generators |
| Mouse Movement / Keystroke Timing | Microscopic uncertainty in user behavior | Linux /dev/random |
Advantages:
- Truly unpredictable
- No periodicity
- Highest security level
Disadvantages:
- Slow generation speed
- Requires specialized hardware
- Higher cost
2.2 Pseudo-Random Numbers (PRNG)
Pseudo-Random Number Generators (PRNGs) use mathematical formulas and an initial value (seed) to generate seemingly random sequences.
Core Concept — The Seed:
The seed is the PRNG’s initial input value. The same seed always produces the same sequence, which is extremely useful in scenarios requiring repeatable experiments (such as scientific simulations and debugging).
Seed = 42 → Sequence: 0.374540, 0.950714, 0.731994, ...
Seed = 42 → Sequence: 0.374540, 0.950714, 0.731994, ... (identical)
Seed = 99 → Sequence: 0.622109, 0.437728, 0.785359, ... (completely different)
Advantages:
- Extremely fast generation
- Good reproducibility (convenient for debugging and testing)
- No special hardware required
Disadvantages:
- Periodic behavior (the sequence eventually repeats)
- Insufficient for cryptographic use (unless using CSPRNG)
2.3 Comparison Summary
| Property | True RNG (TRNG) | Pseudo-RNG (PRNG) | Crypto-Secure PRNG (CSPRNG) |
|---|---|---|---|
| Random Source | Physical phenomena | Mathematical algorithm | Algorithm + entropy source |
| Predictability | Unpredictable | Predictable with seed | Computationally unpredictable |
| Speed | Slow | Very fast | Moderately fast |
| Periodicity | None | Yes | Yes (but extremely long) |
| Reproducible | No | Yes | Usually no |
| Typical Use | Key generation | Games, simulations | Encryption, token generation |
3. Common Pseudo-Random Number Generation Algorithms
3.1 Linear Congruential Generator (LCG)
The Linear Congruential Generator is one of the most classic PRNG algorithms, widely used in the standard libraries of early programming languages.
Formula:
X(n+1) = (a × X(n) + c) mod m
Where:
X(n)is the current stateais the multipliercis the incrementmis the modulusX(0)is the seed
Example (parameters used by Java’s java.util.Random):
a = 25214903917
c = 11
m = 2^48
Pros and Cons:
| Aspect | Rating |
|---|---|
| Speed | ⭐⭐⭐⭐⭐ Extremely fast |
| Statistical Quality | ⭐⭐ Average; hyperplane phenomenon in higher dimensions |
| Period Length | ⭐⭐⭐ Maximum of m |
| Security | ⭐ Not suitable for cryptographic applications |
3.2 Mersenne Twister
The Mersenne Twister (MT19937) is one of the most widely used PRNGs today. Python’s random module and many other languages use it by default.
Key Parameters:
- State space: 19,937 bits
- Period length: 2^19937 − 1 (a Mersenne prime, hence the algorithm’s name)
- Output bits: 32
Characteristics:
- Extremely long period (2^19937 − 1 is an astronomical number with 6,002 digits)
- Uniformly distributed in up to 623 dimensions
- Passes numerous statistical tests
- Not suitable for cryptographic applications (internal state can be recovered from 624 outputs)
3.3 Xorshift Family
The Xorshift algorithm was proposed by George Marsaglia in 2003, known for its extreme speed and minimal implementation.
Basic Xorshift32 Implementation:
function xorshift32(state) {
state ^= state << 13;
state ^= state >> 17;
state ^= state << 5;
return state >>> 0; // Convert to unsigned 32-bit integer
}
Improved Variants:
- xorshift128+: The algorithm used by Firefox and Chrome’s
Math.random() - xoroshiro128: Better statistical properties
- xoshiro256**: One of the currently recommended general-purpose PRNGs
3.4 Algorithm Comparison
| Algorithm | Period Length | Speed | Statistical Quality | Security | Typical Use |
|---|---|---|---|---|---|
| LCG | ≤ m | Very fast | Average | ❌ | Simple simulation, education |
| Mersenne Twister | 2^19937−1 | Fast | Excellent | ❌ | Scientific computing, games |
| Xorshift128+ | 2^128−1 | Very fast | Good | ❌ | Browser JS engines |
| xoshiro256** | 2^256−1 | Very fast | Excellent | ❌ | General simulation |
4. Cryptographically Secure Random Numbers (CSPRNG)
For cryptographic applications, ordinary PRNGs are insufficient. Cryptographically Secure PRNGs (CSPRNGs) must meet much stricter requirements.
4.1 Core Requirements of CSPRNGs
- Forward Secrecy: Even if an attacker knows the current output, they cannot derive previous outputs.
- Backward Secrecy (Prediction Resistance): Even if an attacker knows the current output, they cannot predict future outputs.
- State Recovery Resistance: Even if an attacker obtains partial internal state, they cannot fully recover the generator’s state.
4.2 Common CSPRNG Implementations
| Platform / Language | CSPRNG API | Underlying Mechanism |
|---|---|---|
| Web Browsers | crypto.getRandomValues() | OS entropy pool |
| Node.js | crypto.randomBytes() | OpenSSL |
| Python | secrets module | OS entropy pool |
| Java | SecureRandom | Multiple providers |
| Linux | /dev/urandom | Kernel entropy pool |
| Windows | BCryptGenRandom | CNG |
4.3 Programming Examples
JavaScript (Browser):
// Generate a cryptographically secure random integer
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 - 1;
let randomValue;
do {
const array = new Uint8Array(bytesNeeded);
crypto.getRandomValues(array);
randomValue = array.reduce((acc, byte, i) =>
acc + byte * (256 ** i), 0);
} while (randomValue > maxValid);
return min + (randomValue % range);
}
Python:
import secrets
# Generate a secure random integer
secure_num = secrets.randbelow(100) # 0-99
# Generate a secure random token
token = secrets.token_hex(32) # 64 hexadecimal characters
url_token = secrets.token_urlsafe(32) # URL-safe Base64
# Generate a secure password
import string
alphabet = string.ascii_letters + string.digits + string.punctuation
password = ''.join(secrets.choice(alphabet) for _ in range(16))
5. Probability Distributions of Random Numbers
Different application scenarios require random numbers with different probability distributions.
5.1 Uniform Distribution
The most basic distribution type, where each value has an equal probability of being selected.
- Discrete Uniform: Like rolling a die — each face (1-6) has a 1/6 probability
- Continuous Uniform: Like generating a floating-point number in the range [0, 1)
Use cases: Lotteries, random sorting, random sampling
5.2 Normal Distribution (Gaussian Distribution)
Follows the distribution pattern of many natural phenomena, forming a bell curve.
Parameters: μ (mean) and σ (standard deviation)
~68% of values fall within [μ-σ, μ+σ]
~95% of values fall within [μ-2σ, μ+2σ]
~99.7% of values fall within [μ-3σ, μ+3σ]
Use cases: Grade distribution simulation, height/weight modeling, financial risk assessment
5.3 Exponential Distribution
Describes the waiting time between independent random events.
Use cases: Server request interval simulation, radioactive decay models, queueing theory
5.4 Distribution Summary
| Distribution | Parameters | Typical Shape | Common Applications |
|---|---|---|---|
| Uniform | min, max | Rectangle | Lotteries, dice |
| Normal | μ, σ | Bell curve | Natural phenomena simulation |
| Exponential | λ | Decay curve | Queueing models |
| Poisson | λ | Discrete bell | Event counting |
| Binomial | n, p | Discrete bell | Success counting |
6. Real-World Applications of Random Numbers
6.1 Gaming and Entertainment
Random numbers are one of the cornerstones of game design:
- Dice and Card Simulation: Core mechanics of board games and card games
- Loot Drop Systems: Equipment drop rate calculations in RPGs
- Map Generation: Procedurally generated worlds like Minecraft
- AI Behavior: Random NPC decisions to increase gameplay variety
- Critical Hits and Dodges: Probability-based combat system judgments
6.2 Cryptography and Security
This is the field with the highest quality requirements for random numbers:
- Key Generation: Encryption keys for AES, RSA, and other algorithms must be cryptographically secure random numbers
- Initialization Vectors (IV): Random initial values in encryption modes
- Nonces: One-time random numbers to prevent replay attacks
- Salts: Random prefixes in password hashing
- Token Generation: Session IDs, CSRF Tokens, API Keys, etc.
⚠️ Security Warning: In cryptographic contexts, never use
Math.random()or similar ordinary PRNGs. You must use a CSPRNG (such ascrypto.getRandomValues()).
6.3 Scientific Research and Simulation
- Monte Carlo Methods: Using random sampling to approximate complex mathematical computations
- Molecular Dynamics Simulations: Simulating randomness in particle motion
- Genetic Algorithms: Random mutation and crossover in evolutionary computing
- Statistical Sampling: Randomly selecting samples from large datasets for analysis
Estimating π using the Monte Carlo Method:
import random
def estimate_pi(num_points):
inside = 0
for _ in range(num_points):
x = random.random()
y = random.random()
if x**2 + y**2 <= 1:
inside += 1
return 4 * inside / num_points
# As the number of points increases, the result approaches π
print(estimate_pi(1000)) # ≈ 3.1
print(estimate_pi(100000)) # ≈ 3.14
print(estimate_pi(10000000)) # ≈ 3.1416
6.4 Business and Operations
- A/B Testing: Randomly assigning users to different experimental groups
- Ad Serving: Randomly displaying different ad variants
- Lottery Draws: Fairly selecting winners at random
- Load Balancing: Randomly distributing requests to different servers
6.5 Art and Creativity
- Generative Art: Creating unique visual works through random parameters
- Music Generation: Randomizing notes and rhythms to create new melodies
- Random Text: Lorem Ipsum generation, random poetry, etc.
- NFT Attribute Generation: Random trait combinations for digital artwork
7. How to Correctly Generate Random Integers in a Specific Range
This is a seemingly simple problem that harbors hidden pitfalls.
7.1 Common Incorrect Approach
// ❌ Wrong: Biased due to modulo
function badRandom(min, max) {
return min + Math.floor(Math.random() * (max - min + 1));
}
While the above code is “good enough” for most scenarios, Math.random() itself is not cryptographically secure, and the modulo operation can introduce slight bias.
7.2 The Modulo Bias Problem
When the range of the random number cannot be evenly divided by the target range, modulo bias occurs:
Suppose the random range is 0-9 (10 values), but we want 0-2 (3 values)
0 → 0, 1 → 1, 2 → 2
3 → 0, 4 → 1, 5 → 2
6 → 0, 7 → 1, 8 → 2
9 → 0
Result: 0 appears 4 times, while 1 and 2 each appear 3 times
Probability of selecting 0 = 40%, instead of 33.3%
7.3 Eliminating Modulo Bias
Rejection Sampling:
function unbiasedRandomInt(min, max) {
const range = max - min + 1;
const limit = Math.floor(2**32 / range) * range;
let value;
do {
const buffer = new Uint32Array(1);
crypto.getRandomValues(buffer);
value = buffer[0];
} while (value >= limit);
return min + (value % range);
}
By discarding values that exceed a complete multiple of the range, this ensures each target value has an exactly equal probability of being selected.
8. Random Number APIs Across Programming Languages
8.1 JavaScript
// Basic random numbers (not secure)
Math.random(); // Float in [0, 1)
Math.floor(Math.random() * 100); // Integer 0-99
// Cryptographically secure random numbers
const array = new Uint32Array(10);
crypto.getRandomValues(array); // 10 secure random integers
// Generate random integer in a specific range
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
8.2 Python
import random
# Basic usage
random.random() # Float in [0.0, 1.0)
random.randint(1, 100) # Integer between 1-100 (inclusive)
random.choice([1,2,3,4]) # Pick one randomly from a list
random.shuffle(my_list) # Shuffle list in-place
random.sample(range(100), 10) # Pick 10 unique items from range
# Cryptographically secure
import secrets
secrets.randbelow(100) # Secure random 0-99
secrets.token_hex(16) # 32-character hex secure token
8.3 Java
import java.util.Random;
import java.security.SecureRandom;
// Basic random numbers
Random random = new Random();
int num = random.nextInt(100); // 0-99
double d = random.nextDouble(); // [0.0, 1.0)
// Cryptographically secure
SecureRandom secure = new SecureRandom();
int secureNum = secure.nextInt(100);
byte[] bytes = new byte[32];
secure.nextBytes(bytes);
8.4 Go
import (
"math/rand"
"crypto/rand"
"math/big"
)
// Basic random numbers
n := rand.Intn(100) // 0-99
// Cryptographically secure
max := big.NewInt(100)
secureN, _ := rand.Int(rand.Reader, max)
9. Random Number Quality Testing
How do you evaluate the quality of a random number generator?
9.1 Common Statistical Tests
| Test Name | What It Checks | Description |
|---|---|---|
| Frequency Test | Whether 0s and 1s appear in roughly 50:50 ratio | Most basic test |
| Runs Test | Distribution of consecutive identical bits | Checks for excessive runs of 0s or 1s |
| Poker Test | Distribution of fixed-length subsequences | Checks uniformity of bit patterns |
| Autocorrelation Test | Correlation between the sequence and shifted versions of itself | Detects periodicity |
| Monotone Test | Length of continuously increasing or decreasing runs | Checks for trends |
9.2 Authoritative Test Suites
- NIST SP 800-22: Statistical test suite from the National Institute of Standards and Technology, containing 15 tests
- TestU01: The most comprehensive test suite (SmallCrush, Crush, BigCrush)
- Diehard Tests: Classic suite of statistical tests
- PractRand: Practical random number testing utility
10. Common Misconceptions About Random Numbers
❌ Myth 1: Math.random() Is Sufficient for Security Use
Math.random() uses a PRNG whose output is predictable. It should absolutely never be used for password generation, token generation, encryption keys, or any security-sensitive scenario.
❌ Myth 2: Random Means Non-Repeating
Random numbers can absolutely repeat! If you need non-repeating random numbers, you should generate a sequence first and then shuffle it randomly, or use a rejection sampling strategy.
❌ Myth 3: More Complex Formulas = More Random
Simply applying mathematical transformations to Math.random() (such as taking the sine, logarithm, etc.) does not improve randomness. It can actually introduce bias and destroy uniform distribution.
❌ Myth 4: Timestamps Make Good Random Seeds
Timestamps have limited precision (typically millisecond-level) and can be guessed by attackers. While they can serve as temporary seed sources, they should not be used in security-sensitive scenarios.
❌ Myth 5: Shuffling Only Requires a Few Random Swaps
An incorrect shuffling algorithm will cause certain permutations to appear with higher probability than others. Always use the Fisher-Yates shuffle algorithm:
function fisherYatesShuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
11. Best Practices for Random Number Generation
Choosing the Right Random Number Generator
| Scenario | Recommended Approach | Reason |
|---|---|---|
| Games / Entertainment | Math.random() / PRNG | Fast and sufficient quality |
| Passwords / Keys / Tokens | CSPRNG | High security requirements |
| Scientific Simulations | Mersenne Twister / xoshiro256** | Excellent statistical quality |
| A/B Testing | PRNG + fixed seed | Reproducibility needed |
| Lottery / Raffle | TRNG / CSPRNG | Fairness and regulatory requirements |
Key Principles
- Clarify your security requirements: Don’t use ordinary PRNGs in security contexts
- Understand modulo bias: Use rejection sampling when uniform distribution is needed
- Seed properly: Use high-quality entropy sources as seeds
- Don’t invent your own algorithms: Use well-vetted standard algorithms and libraries
- Consider performance: Choose computationally lightweight algorithms for high-frequency scenarios
12. Frequently Asked Questions
Is Math.random() truly random or pseudo-random?
Math.random() is a pseudo-random number generator. In modern browsers, it typically uses the xorshift128+ algorithm. While the statistical quality is decent, it is not cryptographically secure.
How do I generate a random integer within a specific range in JavaScript?
The simplest approach is:
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
For a cryptographically secure version, use crypto.getRandomValues().
Why are cryptographically secure random numbers needed?
Because ordinary PRNG outputs are predictable. If an attacker can guess your random numbers, they could forge session tokens, break encryption, manipulate lottery results, and more.
How do I generate a sequence of non-repeating random numbers?
Several approaches:
- Fisher-Yates Shuffle: Generate an ordered array then shuffle randomly
- Set Deduplication: Generate random numbers, check for existence, add if absent
- Reservoir Sampling: Suitable for sampling from large data streams
Does a random number generator have “good luck” and “bad luck”?
No. Each generation is independent. Having generated 10 consecutive 1s does not reduce the probability of generating another 1 next time. This belief is known as the “Gambler’s Fallacy.”
13. Conclusion
Random number generation is a topic in computer science that appears simple but is remarkably rich in depth. From basic linear congruential generators to advanced quantum random number generators, from gaming entertainment to national security, applications of random numbers are ubiquitous.
| Key Factor | Recommendation |
|---|---|
| General Purpose | Use the language’s built-in PRNG |
| Security Scenarios | Must use CSPRNG |
| Scientific Computing | Choose algorithms with excellent statistical quality |
| Fairness Requirements | Be aware of modulo bias; consider using TRNG |
| Reproducibility Needs | Use PRNG with a fixed seed |
Understanding the principles and best practices of random number generation helps us choose the right tool for the right scenario, avoiding potential security vulnerabilities and statistical biases.
Want to generate random numbers quickly? Use our Random Number Generator with support for custom ranges, batch generation, and more practical features to meet all your needs.