Fair Draws and Strong Passwords: What Random Actually Means

Most random numbers on the web come from a generator that was never meant to be unpredictable. For a giveaway that matters, or a password, that difference is everything.

There are two kinds of random and they are not interchangeable

Every browser has a function called Math.random. It has been there since the nineties, it is one line to use, and it powers an enormous number of the random pickers, dice rollers and password tools on the web. It is also, by design, not unpredictable.

Math.random is a pseudorandom generator. It starts from a hidden seed and runs a formula. The output looks scattered, passes a casual eyeball test, and is perfectly fine for shuffling a slideshow or jittering an animation. What it is not designed to do is stop someone who has seen a few of its outputs from working out what comes next. MDN says this plainly: Math.random does not provide cryptographically secure random numbers and should not be used for anything related to security.

The other kind is crypto.getRandomValues, which draws from the operating system's own entropy pool, the same source your machine uses for real cryptography. It is not seeded from a formula you can reconstruct. Seeing a thousand outputs tells you nothing about the next one.

The awkward part is that both look identical when you print them. You cannot tell by looking at a number whether it came from a source someone could predict. That is exactly why the distinction gets ignored right up until it matters.

Where it genuinely matters, and where it genuinely does not

I want to be honest about the scope here, because security advice tends to get shouted at people who do not need it.

If you are picking who makes the tea, choosing a random restaurant, or shuffling a playlist, Math.random is completely fine. Nobody is attacking your lunch decision. Reaching for cryptographic randomness there is not wrong, it is just irrelevant.

It starts to matter when the output is worth something to somebody. A giveaway with a real prize, where an entrant with technical skill has a motive to game it. A password, an API key, a token, a reset code. A random assignment in research where predictability would undermine the result. In all of those, the question stops being "does this look random" and becomes "could someone predict it", and only one of the two generators has an answer.

That is why the password generator and the random number generator on this site both use the browser's cryptographic source rather than the convenient one. It costs nothing to use the stronger generator, and the moment you need it you generally do not know that you needed it.

How much randomness a password actually needs

Password strength is not really about symbols and capital letters. It is about entropy, which is a measure of how many equally likely possibilities the attacker has to work through. It is measured in bits, and each extra bit doubles the work.

The arithmetic is simple. A password drawn from an alphabet of N characters, L characters long, has L multiplied by the base-two logarithm of N bits of entropy. Lowercase letters only gives 4.7 bits per character. Adding uppercase and digits takes it to about 5.95. Adding symbols reaches roughly 6.55.

So a 12 character password using upper, lower and digits carries about 71 bits. A 16 character one carries about 95. And a passphrase of five common words drawn from a 7,776 word list carries about 64 bits, which is why long passphrases hold up well despite containing no symbols at all: length is doing the work that punctuation gets credit for.

The thing that quietly destroys all of this is a human choosing the characters. People pick patterns, dates, keyboard runs and substitutions they think are clever, and attackers have known the full catalogue of clever substitutions for twenty years. A 12 character password you invented is worth far less than 71 bits. A 12 character password a good generator produced is worth all of it.

Why a fair draw is harder than picking a number

Say you have 10 entrants and a random source that gives you a number from 0 to 255. The obvious move is to take the remainder after dividing by 10. It is one operation and it is subtly unfair.

There are 256 possible values. Divide them into buckets of 10 and you get 25 complete runs covering 0 to 249, then six values left over: 250 to 255, which land on entrants 0 through 5. Those six entrants get 26 chances each while the other four get 25. That is a 4% edge, invisible in any single draw and perfectly real across enough of them. It is called modulo bias, and it is the most common bug in homemade draw code.

The fix is not complicated. You reject the leftover range and draw again, so every entrant sits in a complete bucket. The cost is the occasional extra draw and the benefit is that the draw is actually fair, which is the only property a draw has.

It matters more than it sounds when you are running something public. If you cannot explain why your draw was fair, the only thing standing behind the result is that people trust you, and a giveaway is precisely the situation where somebody who lost is motivated to ask. The spin the wheel tool and the random number generator both reject rather than fold the leftover range, for that reason.

Random identifiers are a different problem again

A UUID is not trying to be unguessable, it is trying to be unique without anybody coordinating. Version 4 UUIDs are 122 random bits, and the point of that size is collision resistance: two machines that never speak to each other can both mint identifiers all day and never clash.

The numbers here are genuinely hard to hold in your head. You would need around 2.7 quintillion version 4 UUIDs before reaching an even chance of a single collision anywhere in the set, and roughly 103 trillion before the odds even reach one in a billion. In practice, if your generator is drawing from a proper random source, collisions are not a thing you plan for.

The catch is that same word: proper. A UUID generated from a weak source keeps the shape and loses the guarantee, and because the format looks identical you get no warning. If those identifiers ever end up in URLs that act as access, such as an unlisted share link, a predictable generator turns a private link into a guessable one. The UUID generator uses the cryptographic source for that reason, even though uniqueness alone would not require it.

A short checklist

Use the cryptographic source whenever the output guards something, is worth something, or will be published as a result. Use whatever you like for cosmetics.

Prefer length over character-set gymnastics. Sixteen characters of upper, lower and digits beats twelve with symbols crammed in, and it is easier to type on a phone.

Never let a person choose the characters in something that needs to be unpredictable. That includes you, and it especially includes the parts you think are unguessable.

If you are running a draw with a real prize, be able to say how it was done. Rejecting the leftover range costs nothing and is the difference between a fair draw and one that merely looks fair.

One last point that applies to all of it: every one of these tools runs in your own browser, so a password you generate here never crosses the network. That is not a marketing line, it is the only arrangement under which generating a password on a website makes any sense at all.

Questions people ask

Is Math.random safe for passwords?

No. MDN states directly that Math.random does not provide cryptographically secure random numbers and should not be used for anything security related. It is a pseudorandom generator running a formula from a hidden seed, so its output can in principle be predicted. Use crypto.getRandomValues, which is what the password generator here uses.

How long should a random password be?

Sixteen characters from a mix of upper case, lower case and digits gives about 95 bits of entropy, which is comfortably beyond brute force. Twelve gives about 71 bits, which is still strong for most accounts. Length buys more than symbols do, so prefer a longer password over a shorter one stuffed with punctuation.

What is modulo bias in a random draw?

It is the unfairness you get from squashing a range into a smaller one with a remainder. Mapping 0 to 255 onto 10 entrants leaves six values over, so six entrants get 26 chances and four get 25, a 4% edge. The fix is to reject the leftover values and draw again rather than folding them in.

Can two UUIDs ever be the same?

In theory yes, in practice no. A version 4 UUID carries 122 random bits, and you would need around 2.7 quintillion of them before the odds of a single collision anywhere in the set reached even. The real risk is not collision but a weak random source, which keeps the format while quietly removing the guarantee.

Are random numbers generated on this site sent anywhere?

No. Every generator here runs entirely in your browser using its own cryptographic random source. Nothing is transmitted, which is the only sane arrangement for a password: you can load the page, disconnect from the internet, and it will still work.

Is a passphrase better than a random password?

It depends what you need to do with it. Five words drawn at random from a 7,776 word list carry about 64 bits, which is decent and far easier to type or remember than a random string. For anything stored in a password manager, where you never type it, a longer random password is the better trade.

Read next

All articles
6 min read

Why Your GIF Is 20MB When the Video Was 2MB

A GIF stores every frame as a picture. A video stores what changed. That one difference explains the file size, the grainy colours, and why most platforms quietly convert your GIF anyway.