Skip to content
Logo Any Help Me

Why True Randomness Matters for Giveaways and Games

By Any Help Me Tech Team

High-tech conceptual illustration of glowing digital dice inside a highly secure vault

Have you ever run an Instagram giveaway, picked a random winner from a list of 5,000 comments using a simple, free online tool, and wondered: Was that actually fair?

The surprising, slightly terrifying answer is: often, no.

The vast majority of free online tools, and even the basic programming languages used to build them, rely on something called a Pseudo-Random Number Generator (PRNG). Understanding the fatal flaw in PRNGs is crucial if you are running anything that involves money, prizes, sensitive data, or security.

The Illusion of Pseudo-Randomness

Computers are fundamentally deterministic, rule-following machines. They take an input, follow strict logic, and produce an output. Because of this rigid nature, it is actually incredibly difficult for a computer to do something truly spontaneous or unpredictable.

To fake it, standard PRNGs (like the Math.random() function built into your web browser) use a mathematical formula and a “seed” (usually the exact millisecond on the computer’s internal clock when you clicked the button). This formula spits out a sequence of numbers that looks completely random to a human.

However, it’s an illusion. If a clever attacker knows the algorithm being used and the exact time the button was clicked, they can perfectly predict what the “random” number will be before it is even generated.

For a simple video game animation or a harmless playlist shuffle, this is perfectly fine. For a lottery draw, a cryptographic key, or a high-stakes giveaway, it is disastrous.

How PRNGs Actually Work Under the Hood

The most common PRNG algorithm in programming is called a Linear Congruential Generator (LCG). It uses a simple formula:

next = (a × current + c) mod m

Where a, c, and m are fixed constants, and current starts with the seed value. Each call to the function takes the previous result, plugs it back into the formula, and produces the next number in the sequence.

The critical word here is sequence. A PRNG doesn’t generate random numbers. It generates a fixed, repeatable sequence of numbers that merely appears random. Give it the same seed, and you get the exact same sequence every time. This is actually useful for testing and debugging (you can reproduce “random” results), but it’s terrible for security.

Modern JavaScript engines use more sophisticated algorithms like xoshiro128 or xorshift128+ for Math.random(), which produce better statistical distribution than a basic LCG. But the fundamental weakness remains: they are deterministic. Given the internal state, every future output is predictable.

The Gold Standard: Cryptographically Secure Randomness

To solve this problem, modern web browsers introduced something called the Web Crypto API.

Instead of relying on a simple math formula and a predictable clock, the Web Crypto API gathers “entropy” (a measure of chaos or disorder) from the physical environment. It looks at microscopic, unpredictable fluctuations in your computer’s CPU temperature, the exact nanosecond timing of your mouse movements, disk I/O timing jitter, and background system noise to generate a truly unpredictable seed.

This results in a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG). It is so robust and secure that it is the exact same underlying technology used to generate banking encryption keys and secure your passwords.

PRNG vs CSPRNG: A Side-by-Side Comparison

FeatureMath.random() (PRNG)crypto.getRandomValues() (CSPRNG)
Predictable with known state?YesNo
Entropy sourceInternal algorithm + clockOS hardware noise, I/O timing
SpeedVery fastSlightly slower
Suitable for games/animationYesYes (overkill but works)
Suitable for lotteries/prizesNoYes
Suitable for cryptographic keysNoYes
Suitable for security tokensNoYes

Beware of Modulo Bias

Here is the tricky part: even if a tool uses secure randomness under the hood, it can still fail if the developer uses bad math to scale the number to your desired range.

For example, if you want to pick a number between 1 and 100, many developers use a basic mathematical operation called a “modulo”. However, due to how binary division works, using a simple modulo creates a phenomenon called Modulo Bias, where the lower numbers mathematically have a slightly higher chance of being picked than the higher numbers.

Why Modulo Bias Happens

Imagine a random number generator that produces values 0-255 (a single byte). You want a number from 0 to 99, so you compute randomByte % 100:

  • Values 0-99 map directly: 0→0, 1→1, … 99→99
  • Values 100-199 also work: 100→0, 101→1, … 199→99
  • But values 200-255 only map to 0-55: 200→0, 201→1, … 255→55

Numbers 0-55 can be produced by three source values each, while numbers 56-99 can only be produced by two. This means picking 0-55 is 50% more likely than picking 56-99.

It is the digital equivalent of using loaded dice.

The effect here is not small at all. A specific low outcome comes up 1.17% of the time against 0.78% for a high one. The low half is 50% more likely, and every low number sits 17% above where a fair draw would put it. The size of the distortion depends on how badly your range divides into the generator’s range, which is why it has to be handled rather than assumed away. In a giveaway with 5,000 entrants, certain positions in the list would have a measurably higher chance of winning.

The Fix: Rejection Sampling

The correct approach is called rejection sampling. Instead of forcing every random value into your target range, you discard (reject) any value that would cause bias and draw again:

  1. Generate a random number in the full range (0-255)
  2. If it falls in the biased region (200-255 in our example), throw it away
  3. Draw another random number
  4. Repeat until you get one in the unbiased region (0-199)
  5. Apply the modulo to the unbiased value

This guarantees a perfectly uniform distribution across your target range. How often you discard depends on the fit between the two ranges: in the example above you would throw away 56 of every 256 draws, about 22%. That sounds wasteful and costs nothing noticeable, because generating another random byte takes nanoseconds. Correctness is worth far more than the discarded draws.

Real-World Consequences of Bad Randomness

These aren’t theoretical concerns. History is littered with high-profile failures caused by weak random number generation:

  • Online poker scandals: In the late 1990s, several online poker platforms used simple PRNGs seeded with the system clock. Researchers demonstrated they could predict the exact deck order by observing just a few dealt cards, allowing them to know every player’s hand.
  • Predictable session tokens: Websites that generate login session IDs with weak PRNGs can be exploited by attackers who predict valid session tokens and hijack user accounts.
  • Blockchain vulnerabilities: Weak randomness in smart contract systems has led to millions of dollars in losses when attackers could predict “random” outcomes in blockchain-based games and lotteries.
  • RSA key generation: In 2012, researchers found that 0.2% of RSA public keys on the internet shared a prime factor due to poor entropy at boot time, allowing them to derive private keys and compromise those systems.

What About Hardware Random Number Generators?

Some systems go even further than the Web Crypto API by using dedicated hardware to generate randomness:

  • Intel RDRAND: Modern Intel and AMD CPUs include a built-in hardware random number generator instruction that draws from thermal noise in the silicon.
  • Lava lamp walls: Cloudflare famously uses a wall of lava lamps filmed by a camera as an entropy source for their encryption infrastructure.
  • Radioactive decay: Some laboratories use Geiger counters measuring the decay of radioactive isotopes, which is governed by quantum mechanics and is fundamentally unpredictable.

For most applications, the OS-level entropy collected by the Web Crypto API is more than sufficient. Hardware RNGs are mainly used in specialized contexts like HSMs (Hardware Security Modules) at banks and certificate authorities.

The Solution: What to Look for in a Random Generator

If you are running a raffle, picking a contest winner, or generating secure test data, you need a tool that:

  1. Uses the Web Crypto API (crypto.getRandomValues), not Math.random()
  2. Employs rejection sampling to eliminate modulo bias
  3. Runs locally in your browser so no one can intercept or manipulate the results
  4. Is transparent about its methodology

Our free Random Number Generator does exactly this. It runs entirely locally in your browser, meaning it is 100% private, instantaneous, and mathematically proven to be fair. For picking names or items from a list, try our Random Picker Wheel, which has the same cryptographic fairness with a fun visual spin. And if you need coin flips or dice rolls for tabletop games, our Coin Flip & Dice Roller also uses the Web Crypto API for every roll.

Next time you run a giveaway, don’t leave it up to a flawed clock algorithm. You can draw the winner with absolute, cryptographically secure confidence.

← Back to all articles