Ctrl + K
Security21 min read

Random Number Generation Explained

A practical guide to random number generation covering PRNGs, CSPRNGs, entropy, seeds, random integers and decimals, security-sensitive applications and common implementation mistakes.

Published: 2026-10-05

Random numbers are used in far more places than games and simulations. Modern applications rely on random values for session identifiers, API keys, password-reset tokens, cryptographic operations, randomized algorithms, testing, sampling, simulations and many other tasks.

However, not every kind of randomness is suitable for every purpose. A random number generated for a game does not necessarily need the same properties as a random value used as an authentication token. In security-sensitive applications, the distinction between ordinary pseudo-randomness and cryptographically secure randomness is critical.

This guide explains how random number generation works, what pseudo-random number generators and cryptographically secure random number generators are, why seeds matter, what entropy means and how to choose an appropriate random source for a particular task.

What Is a Random Number?

A random number is a value produced according to some probability distribution where the outcome cannot be reliably determined in advance from the information available to the observer.

In practice, software cannot simply ask a computer to produce a mathematically perfect random number from nothing. Instead, random-number systems use algorithms, internal state and, in some cases, physical sources of unpredictable environmental data.

The exact meaning of random therefore depends on the application. A simulation may require values that follow a particular statistical distribution. A game may need unpredictable outcomes from the player's perspective. A security system may require values that an attacker cannot feasibly predict.

True Randomness vs Pseudo-Randomness

Random number generation is commonly divided into two broad categories: true or physical randomness and pseudo-random number generation.

TypeBasic ideaTypical use
Physical randomnessUses measurements of physical phenomenaEntropy sources and specialized hardware
PRNGUses a deterministic algorithm and internal stateGames, simulations, testing and randomized algorithms
CSPRNGUses cryptographic algorithms and unpredictable system entropyTokens, keys, sessions and security-sensitive values

A CSPRNG is still algorithmic and therefore deterministic internally, but it is designed so that its outputs remain computationally unpredictable without access to the generator's internal state and required secret information.

What Is a PRNG?

PRNG stands for Pseudo-Random Number Generator. A PRNG is an algorithm that produces a sequence of values that appears random according to relevant statistical properties.

seed → PRNG state → value → updated state → value → updated state

The important word is pseudo. Given the same initial state or seed and the same algorithm, a deterministic PRNG can produce the same sequence again.

This property is extremely useful. Reproducibility is often desirable in simulations, automated tests and debugging because developers can recreate the same sequence of values.

Why PRNGs Are Useful

  • They are usually fast.
  • They can generate very large numbers of values.
  • Their sequences can be reproducible.
  • They are useful for simulations and randomized algorithms.
  • They can provide good statistical distributions.

A good PRNG is not automatically a bad generator. It is simply designed for a different problem than a cryptographically secure generator.

Why Ordinary PRNGs Should Not Be Used for Security

Many ordinary PRNGs are designed around speed and statistical quality rather than resistance to prediction attacks. If an attacker can observe enough output or infer the generator's state, future values may become predictable.

const value = Math.random();

JavaScript's Math.random() is intended for general-purpose pseudo-random values, not for generating secrets. It should not be used for password-reset tokens, session identifiers, API keys, authentication challenges or cryptographic keys.

⚠️ Do not use Math.random(), a simple timestamp, an incrementing counter or a predictable seed to generate security-sensitive tokens.

What Is a CSPRNG?

CSPRNG stands for Cryptographically Secure Pseudo-Random Number Generator. A CSPRNG is designed to produce output that is computationally difficult to predict even when an attacker knows the algorithm and may have observed previous outputs.

Modern operating systems provide cryptographic randomness facilities that applications can access through standard APIs. These systems collect entropy from multiple sources and use cryptographic algorithms to generate random-looking output.

The application normally does not need to implement the underlying generator itself. Using the operating system or runtime's established cryptographic random API is generally safer than designing a custom random algorithm.

JavaScript Secure Randomness

Web applications can use the Web Crypto API to obtain cryptographically strong random values.

const bytes = new Uint8Array(32);

crypto.getRandomValues(bytes);

The returned bytes can then be encoded into hexadecimal, Base64url or another suitable representation depending on how the value will be stored or transmitted.

const bytes = new Uint8Array(32);
crypto.getRandomValues(bytes);

const token = Array.from(bytes, byte =>
  byte.toString(16).padStart(2, "0")
).join("");

For security-sensitive applications, using the platform's established cryptographic APIs is preferable to implementing a custom PRNG.

Node.js Secure Randomness

Node.js provides cryptographic random functionality through its crypto APIs.

import { randomBytes } from "node:crypto";

const token = randomBytes(32).toString("hex");

This approach produces a cryptographically strong random byte sequence suitable for many security-sensitive token-generation tasks.

What Is Entropy?

Entropy is a measure of uncertainty. In the context of random-number generation, more entropy generally means that there are more possible unpredictable outcomes available to the system.

For a uniformly distributed random value with N equally likely possibilities, the information content can be expressed as log₂(N) bits.

For example, a single uniformly random bit has two possible outcomes, 0 and 1, corresponding to one bit of entropy. Four independent random bits can represent 16 equally likely combinations and therefore provide four bits of entropy.

1 bit  → 2 possible values
2 bits → 4 possible values
4 bits → 16 possible values
8 bits → 256 possible values

Entropy Is Not the Same as Length

A long string is not necessarily highly random. If its contents are predictable, the string may contain very little effective entropy despite having many characters.

20260929153000000000000000000000

The value above is long, but much of it may be predictable if it represents a timestamp followed by fixed characters. A shorter value generated from a strong random source can contain significantly more useful entropy.

Alphabet Size and Random Strings

When random numbers are encoded as strings, the alphabet affects how much information each character can represent.

AlphabetApproximate information per character
Binary1 bit
Hexadecimal4 bits
Base325 bits
Base646 bits
62-character alphanumeric alphabetAbout 5.95 bits

This is why a 32-character hexadecimal string and a 32-character alphanumeric string do not represent the same number of possible values.

What Is a Seed?

A seed is an initial value used to initialize the state of a deterministic pseudo-random number generator.

seed → deterministic sequence of pseudo-random values

If the same PRNG algorithm receives the same seed and starts from the same state, it can produce the same sequence. This makes seeds extremely useful for reproducible simulations and tests.

Why Reproducible Randomness Is Useful

Suppose a simulation produces a rare bug after generating thousands of random events. If the random sequence can be reproduced from a known seed, developers can rerun the simulation and investigate the same sequence of events.

The same technique is useful in testing machine-learning experiments, procedural generation, game development and statistical simulations.

const rng = createSeededGenerator(12345);

const first = rng();
const second = rng();
const third = rng();

The exact seeded-generator API varies by library. The important concept is that the seed makes the pseudo-random sequence reproducible.

Why Predictable Seeds Are Dangerous

A predictable seed can make an otherwise complicated pseudo-random sequence predictable. Using the current time, process ID or another easily guessed value as the seed is therefore inappropriate for security-sensitive random values.

⚠️ Do not seed authentication tokens or cryptographic secrets with the current timestamp, user ID or another predictable application value.

Random Integer Generation

Many applications need a random integer within a range rather than a raw random byte sequence.

const min = 1;
const max = 100;

const value =
  Math.floor(Math.random() * (max - min + 1)) + min;

This pattern is useful for ordinary non-security-sensitive applications, but it should not be used when the generated value controls authentication, authorization, secrets or other security-sensitive behavior.

Random Integer Bias

Generating a random integer in a range requires more care than simply taking a random byte and applying a remainder operation. If the source space is not evenly divisible by the target range, some results can become more likely than others.

const value = randomByte % 10;

If randomByte can contain 256 equally likely values, 256 is not evenly divisible by 10. Some digits would therefore occur more frequently than others.

A secure range generator can solve this problem using rejection sampling: values outside an evenly divisible portion of the source range are discarded and regenerated.

Cryptographically Secure Random Integers

Modern runtimes provide APIs or libraries that can generate secure random integers within ranges without requiring developers to implement rejection sampling manually.

When the integer affects security decisions, use a well-tested cryptographic API rather than adapting an ordinary Math.random() formula.

Random Decimal Numbers

Random decimal values are commonly used in simulations, visualization, testing and other applications where continuous-looking values are useful.

const value = Math.random();

This produces a pseudo-random floating-point value according to the runtime's implementation. For ordinary simulation or UI purposes, this can be perfectly appropriate.

For security-sensitive applications, however, do not assume that a random-looking decimal is suitable simply because it came from a random function. Use an appropriate cryptographic API when unpredictability matters.

Uniform Distribution

A uniform distribution means that outcomes within the defined range have equal probability, subject to the precision and representation of the generator.

Uniform randomness is useful for many tasks, but not every application needs a uniform distribution. Scientific simulations and statistical models often require distributions such as normal, exponential or Poisson.

Random Numbers From Other Distributions

A PRNG usually produces values from a base distribution, often uniform. Algorithms can then transform those values into other statistical distributions.

DistributionExample use
UniformRandom selection and general simulation
NormalStatistical models and simulations
ExponentialWaiting-time models
PoissonEvent-count simulations

Randomness in Games

Games commonly use pseudo-random number generators because performance and reproducibility can be more important than cryptographic unpredictability.

A game may use a seeded PRNG so that the same game state produces the same sequence of events. This can be useful for replays, deterministic simulations and debugging.

If the random outcome has real-world monetary value or can be exploited to gain an advantage, the requirements may be substantially different and cryptographically secure randomness may become important.

Randomness in Simulations

Scientific and engineering simulations frequently need reproducible pseudo-random sequences. Researchers can store the seed and rerun the same experiment later.

This is one reason PRNGs remain important despite the existence of cryptographically secure generators. Security is not always the primary requirement.

Randomness in Testing

Randomized tests can explore a much larger set of inputs than a small collection of manually written test cases.

const input = generateRandomTestData();

expect(processInput(input)).toSatisfyTheContract();

For reliable debugging, randomized tests should usually record the seed or generated input so a failing case can be reproduced.

Randomness in Cryptography

Cryptographic systems rely heavily on unpredictable random values. Keys, nonces, initialization values, salts, challenges and tokens can all depend on secure randomness.

A weakness in random-number generation can undermine an otherwise mathematically sound cryptographic system. Historically, failures in entropy collection or predictable random generators have resulted in serious security vulnerabilities.

⚠️ Cryptographic algorithms cannot compensate for a fundamentally predictable secret value. If a private key or authentication token is generated from predictable randomness, the security of the surrounding system can be compromised.

Randomness for Password Reset Tokens

Password-reset links commonly contain a random token that proves possession of a previously issued recovery capability.

https://example.com/reset?token=RANDOM_SECRET_VALUE

Such tokens should be generated using cryptographically secure randomness and should expire after a limited period. They should also be invalidated after successful use when the application design permits it.

Randomness for Session IDs

Session identifiers are bearer credentials in many web applications. If an attacker can guess a valid session ID, they may be able to impersonate the associated user.

For this reason, session identifiers should use a cryptographically secure random source and sufficient entropy. A predictable PRNG or timestamp-based value is inappropriate.

Randomness for API Keys

API keys should also be generated from a cryptographically secure source. A sufficiently long random secret makes brute-force guessing impractical when combined with appropriate rate limiting and key management.

import { randomBytes } from "node:crypto";

const apiKey = randomBytes(32).toString("base64url");

The API key should be treated as a secret after generation. It should not be unnecessarily exposed in client-side code, logs or URLs.

Randomness and UUIDs

Random-number generation is also used inside some identifier formats. UUID v4, for example, uses randomly generated bits as the primary source of uniqueness.

This does not mean that every UUID is appropriate for every security purpose. A UUID can be a useful identifier without being treated as an authentication credential.

Entropy vs Collision Resistance

Entropy and collision resistance are related but should not be treated as identical concepts. Entropy describes uncertainty in the generated value, while collision resistance concerns the likelihood that two independently generated values are equal.

A system can be designed with a large identifier space and still have poor security if its generator is predictable. Conversely, a value can be difficult to predict without necessarily being suitable for a particular cryptographic protocol.

Hardware Random Number Generators

Some systems include hardware components capable of measuring physical phenomena that provide unpredictable data. Examples can include electronic noise or other physical processes.

Operating systems can collect and manage entropy from hardware and software sources before exposing a standardized cryptographic random interface to applications.

Application developers generally do not need to access hardware randomness directly. Relying on the operating system's cryptographic randomness facility is usually the safer abstraction.

Why You Usually Should Not Build Your Own CSPRNG

Designing a secure random-number generator requires expertise in cryptography, entropy management, state handling and resistance to prediction attacks.

Established operating-system and runtime APIs have already solved these problems and are maintained as part of the platform's security infrastructure.

💡 For security-sensitive randomness, use a well-established cryptographic API provided by the operating system or runtime instead of inventing your own random algorithm.

Random Seed Generators

A random seed generator can be useful when you need an unpredictable starting point for a reproducible or configurable PRNG-based process.

However, whether the seed itself needs to be secret depends on the application. A simulation seed can be intentionally public, while a seed used as part of a security-sensitive protocol must be handled according to the protocol's security requirements.

Random Number Generation in the Browser

Browser applications have access to two conceptually different sources: Math.random() for ordinary pseudo-random values and the Web Crypto API for cryptographically secure random values.

const ordinary = Math.random();

const secureBytes = new Uint8Array(16);
crypto.getRandomValues(secureBytes);

The correct choice depends on what the value is used for. Do not use the secure API merely because every random number is a security problem, but do not use Math.random() when unpredictability is a security requirement.

Random Number Generation in Next.js Applications

Next.js applications can generate random values on both the server and client, but security-sensitive values should generally be created in a trusted server-side environment.

For example, a server can generate a password-reset token, store an appropriate representation and send only the required token to the user. A browser should not be responsible for generating an authentication secret that the server is expected to trust.

Randomness and Server-Side Rendering

Random values generated during server rendering can cause a different value to be produced during client hydration if the same computation runs again. This can create hydration mismatches in frameworks such as React and Next.js.

Random values that are part of stable rendered content should therefore be generated and passed deliberately rather than regenerated independently on the server and client.

Randomness in Distributed Systems

Distributed systems often need independent services to generate identifiers without coordinating every operation through one central server.

Cryptographically strong random values or carefully designed distributed ID formats can provide sufficiently large identifier spaces so independent generation remains practical.

Time-ordered identifiers such as UUID v7, ULID and KSUID add another option when ordering is important.

Common Random Number Generation Mistakes

Using Math.random() for Security

This is one of the most common mistakes in JavaScript applications. Math.random() is useful for ordinary random behavior but is not intended to generate secrets.

Using Timestamps as Random Values

A timestamp can provide a unique-looking value in some limited situations, but it contains highly predictable information. It should not be used as a replacement for secure randomness.

Adding Randomness to a Predictable Value

Appending a few random characters to a timestamp does not automatically make the result secure. The security properties depend on the entropy and generation method of the random component.

Using Too Few Random Bits

A token with only a small number of possible values can be brute-forced even if every value is generated uniformly. Security-sensitive tokens need enough entropy for the threat model and expected lifetime.

Modulo Bias

Mapping random values to a smaller range with a simple modulo operation can produce a non-uniform distribution when the source range is not evenly divisible by the target range.

Reusing Random State Incorrectly

A PRNG's internal state must be managed correctly. Accidentally copying, resetting or reusing state can cause repeated sequences and undermine the assumptions made by the application.

Confusing Randomness With Security

A value can look random without providing meaningful security. Security requires considering the generator, entropy source, attacker knowledge, token lifetime, rate limiting, storage and the surrounding protocol.

How to Choose a Random Generator

RequirementRecommended approach
Game effectOrdinary PRNG
SimulationSeeded PRNG when reproducibility is useful
Random test dataPRNG with recorded seed
Random UI behaviorOrdinary PRNG
Session tokenCSPRNG
Password-reset tokenCSPRNG
API keyCSPRNG
Cryptographic key materialCryptographic randomness through an established API
Database identifierUUID, UUID v7, ULID or another appropriate ID generator

A Practical Checklist

  • Determine whether the value is security-sensitive.
  • If security matters, use a CSPRNG provided by the platform.
  • Estimate how many possible values the generator can produce.
  • Consider collision probability for identifiers.
  • Choose an appropriate distribution for simulations.
  • Use a reproducible seed when deterministic testing is useful.
  • Avoid predictable seeds for security-sensitive values.
  • Avoid modulo bias when mapping secure random values into ranges.
  • Do not expose secrets unnecessarily in URLs or logs.
  • Do not implement a custom cryptographic random generator unless there is a specialized reason.

Random Number Generation vs Random ID Generation

Random numbers and random identifiers overlap but are not identical problems. A random-number generator may be designed to produce values from a statistical distribution, while an ID generator is usually concerned with uniqueness, representation and sometimes ordering.

TaskImportant property
SimulationStatistical distribution and reproducibility
Random selectionUniformity or required distribution
Database IDUniqueness and storage/index behavior
Session tokenUnpredictability and entropy
API keyUnpredictability, entropy and secret handling

Frequently Asked Questions

What is the difference between PRNG and CSPRNG?

A PRNG is a deterministic algorithm designed to produce statistically useful pseudo-random sequences. A CSPRNG is specifically designed so that its output is computationally difficult to predict and is therefore appropriate for security-sensitive values.

Is Math.random() secure?

No. Math.random() is intended for ordinary pseudo-random behavior and should not be used to generate passwords, session tokens, API keys or other security-sensitive secrets.

What is entropy in random number generation?

Entropy describes uncertainty or information content. For equally likely outcomes, the number of entropy bits corresponds to the base-2 logarithm of the number of possible outcomes.

How many random bits does a secure token need?

There is no single universal number. The appropriate amount depends on the threat model, token lifetime, rate limiting, attack surface and the required security margin. Security-sensitive tokens should be generated using a cryptographically secure random source.

Should I use a random seed for security?

A predictable seed is not suitable for security. Security-sensitive systems should rely on a cryptographic random source rather than attempting to construct security from a manually selected seed.

Why is modulo bias a problem?

If the source range cannot be divided evenly by the desired range, a simple modulo operation makes some outputs more likely than others. Secure range generators can avoid this with techniques such as rejection sampling.

Can random numbers be reproduced?

Yes. Seeded PRNGs are specifically designed for reproducibility. The same algorithm and seed can produce the same sequence, which is useful for simulations, tests and debugging.

Helpful Randomness Tools

A Random Number Generator is useful for ordinary integer or range-based random values, while a Random Decimal Generator can produce random decimal values for simulations, testing and other non-security-sensitive tasks.

For security-sensitive values, use a Secure Random Generator designed around cryptographically strong randomness. An Entropy Calculator can help estimate the amount of information available in an identifier or random string, while a Random Seed Generator is useful when a reproducible PRNG-based process needs a fresh seed.

Conclusion

Random number generation is not one single technology. Ordinary PRNGs, seeded generators and cryptographically secure random generators solve different problems.

For games, simulations, testing and many ordinary application features, a conventional PRNG can provide excellent performance and useful reproducibility. For sessions, password-reset tokens, API keys and cryptographic operations, the application should use a cryptographically secure random source provided by the operating system or runtime.

Entropy, identifier-space size, collision probability, distribution and unpredictability all matter, but they answer different questions. Understanding those differences makes it much easier to choose an appropriate generator instead of treating every random-looking value as equivalent.

The most important rule is simple: use ordinary pseudo-randomness when you need statistical randomness, speed or reproducibility, and use cryptographically secure randomness whenever an attacker must not be able to predict the generated value.

Found an issue?

Found an error, outdated information, or something missing from this article? Let me know through the Contact page.

Your feedback helps improve our articles and keep them accurate and useful.