How Random Number Generators Work

Not all randomness is equal. The difference between a pseudo-random number generator and a cryptographically secure one determines whether your coin flip, dice roll, or name draw is truly fair — or quietly predictable.


What Is a Random Number Generator?

A random number generator (RNG) is an algorithm or hardware device that produces a sequence of numbers with no discernible pattern. Computers face a fundamental problem here: they are deterministic machines. Given the same starting state, a CPU will always produce the same output. True hardware randomness requires an external source of unpredictability — called entropy — such as thermal noise, disk timing variation, or mouse movement.

Software RNGs solve this by either gathering real entropy from the operating system or by using a mathematical formula to simulate randomness. These two approaches produce very different results.

Pseudo-Random Number Generators (PRNG)

A pseudo-random number generator (PRNG) starts from internal state and applies a deterministic algorithm to produce each successive number. The output can look random, but the same initial state produces the same sequence.

JavaScript's Math.random() uses an implementation-defined PRNG. The JavaScript specification does not require a particular algorithm and explicitly does not make the output cryptographically secure. It is therefore inappropriate when unpredictability or auditable fairness matters.

For most purposes — animations, shuffling a playlist, picking a random background color — this does not matter. But for anything where fairness is at stake (giveaways, team draws, game outcomes), predictability is a genuine problem.

Cryptographically Secure PRNGs (CSPRNG)

A cryptographically secure pseudo-random number generator (CSPRNG) is designed so that prior outputs do not make future outputs practically predictable. Compared with a general-purpose PRNG, it provides properties needed by security-sensitive and fairness-sensitive applications:

  • Next-bit unpredictability: Knowing any number of previous outputs gives no statistically significant advantage in predicting the next output.
  • Strong platform entropy: The generator is seeded and refreshed by the operating system rather than application timestamps or other easily guessed values.

Browsers obtain cryptographically strong values from operating-system facilities. The exact entropy sources and algorithms are platform details, so web applications should use the Web Crypto API rather than attempting to collect or manage entropy themselves.

The Web Crypto API: crypto.getRandomValues()

Browsers expose CSPRNG functionality through the Web Crypto API. The key function is crypto.getRandomValues(typedArray), which fills a typed array with cryptographically random bytes sourced from the OS entropy pool.

To generate an unbiased integer in a range, Randly reads a 32-bit value (or combines values for wider safe-integer ranges) and rejects the short tail that would otherwise create modulo bias:

function randomUint32() {

const array = new Uint32Array(1);

crypto.getRandomValues(array);

return array[0];

}

function randomInt(min, max) {

const range = max - min + 1;

const limit = Math.floor(2 ** 32 / range) * range;

let value;

do value = randomUint32(); while (value >= limit);

return min + (value % range);

}

A Uint32Array provides 2³² possible values; Randly combines 53 bits when a wider safe-integer range is needed. Rejection sampling ensures each output in the requested range corresponds to the same number of source values, so no result receives a larger share merely because the requested range does not divide the source range evenly.

Why It Matters for Fairness

For most casual uses, the distinction is invisible. But consider a classroom teacher using a name picker to call on students, or an organization running a prize draw. A general-purpose PRNG is not specified for adversarial use, while a platform CSPRNG is designed to keep future values unpredictable. An audited process is still appropriate for regulated or high-value draws.

Math.random() (PRNG)

  • • Deterministic given the seed
  • • No cryptographic unpredictability guarantee
  • • Fast — suitable for animations and visuals
  • • Not suitable for security or fair draws

crypto.getRandomValues() (CSPRNG)

  • • Supplied by the operating-system CSPRNG
  • • Designed to resist output prediction
  • • Slightly slower (negligible for tool use)
  • • Appropriate primitive for secure randomness

How Randly Uses Randomness

Every tool on Randly — dice rolls, coin flips, name picks, wheel spins, color generation — uses crypto.getRandomValues() exclusively. The implementation lives in a single shared module (lib/random.ts) that exports typed functions: randomInt(min, max), randomIndex(length), randomElement(array), and shuffleArray(array).

No call to Math.random() exists in any tool logic. The only place standard PRNG values appear is in Framer Motion animation parameters (floating element starting positions), which are purely cosmetic and have no effect on tool outcomes.

Common Misconceptions

"Clicking faster makes the result more random."

Timing your click has no effect when using a CSPRNG. The entropy pool is continuously refreshed by the OS regardless of user interaction.

"Running the same tool twice in a row gives correlated results."

Each call to crypto.getRandomValues() is independent. Previous outputs provide no information about future ones.

"A longer list means someone at the end is less likely to be picked."

Random index selection gives every position an equal 1/n probability, regardless of list length.


Try the Tools

All Randly tools use cryptographically secure randomness. No sign-up required.

→ Random Name Picker→ Dice Roller (d2–d100)→ Coin Flip→ Wheel Spinner

Randly

Small tools for easier decisions.

All toolsRoad mapPrivacyTermsContactLearnHelp

© 2026 Randly. All rights reserved.