Published
Password strength is one of the few security questions with an exact answer. It is not a feeling, a colour-coded meter, or a count of special characters — it is a number of bits, and you can compute it from two facts: how many symbols the generator could have chosen from, and how many it chose. Everything else in this guide follows from that arithmetic.
Entropy is the only measurement that means anything
If a password is drawn uniformly at random from an alphabet of N symbols and is L symbols long, its entropy is L × log2(N) bits. That is the whole formula. Sixteen characters drawn from the 95 printable ASCII symbols is 16 × 6.57 ≈ 105 bits. Twelve characters drawn from the 62 alphanumerics is 12 × 5.95 ≈ 71 bits.
The crucial word is uniformly at random. The formula describes the work an attacker faces when they know your generation scheme and must search it exhaustively — which is the assumption you should always make, because generators are public and schemes leak. It says nothing about a password a human invented. Tr0ub4dor&3 has fourteen characters from a 95-symbol alphabet, but it was not drawn from that alphabet uniformly; it was drawn from the much smaller set of words-with-predictable-substitutions, and a cracking rule set searches that set directly. Strength estimators that count character classes systematically overstate human-chosen passwords and understate passphrases.
80 bits is a reasonable floor for anything an attacker might attack offline. 128 bits is the point where the password stops being the weak link under any plausible hardware. Lengths are rounded up.
| Alphabet | Symbols | Bits per symbol | Length for 80 bits | Length for 128 bits |
|---|---|---|---|---|
| Digits only (a PIN) | 10 | 3.32 | 25 | 39 |
| Lowercase letters | 26 | 4.70 | 18 | 28 |
| Lowercase and digits | 36 | 5.17 | 16 | 25 |
| Mixed-case alphanumerics | 62 | 5.95 | 14 | 22 |
| All printable ASCII | 95 | 6.57 | 13 | 20 |
| EFF long wordlist (per word) | 7776 | 12.92 | 7 words | 10 words |
Length beats complexity, and the standards agree
Look at the table again and notice how little the alphabet buys you: widening it from 62 symbols to all 95 printable ASCII saves one character at 80 bits and two at 128. Adding a character to a lowercase-only password buys 4.7 bits. Length is simply the more efficient lever, and the one humans tolerate.
Composition rules — one uppercase, one digit, one symbol — do the opposite of what they promise. They do not increase the entropy of a randomly generated password at all; in fact, requiring specific classes shrinks the space slightly by excluding valid combinations. What they do is force humans into predictable patterns: the capital goes first, the digit and the exclamation mark go last, and the substitution is a for @. Cracking tools encode those patterns as rules and try them first.
This is no longer a contrarian position. NIST SP 800-63B, in Revision 4 finalised in 2025, tells verifiers not to impose composition rules, to accept at least 64 characters, to accept all printing ASCII plus space and Unicode, and to check candidate passwords against a corpus of known-breached values. It keeps an 8-character absolute minimum and adds a recommendation that verifiers require at least 15. Truncating a password, silently stripping characters, or rejecting spaces are all treated as defects.
Where the randomness comes from decides everything
Math.random is the canonical mistake. It is specified to return a number in [0, 1) with approximately uniform distribution, and that is all it is specified to do — the ECMAScript standard explicitly declines to require unpredictability. V8 implements it with xorshift128+, a fast non-cryptographic generator with 128 bits of internal state. Its state can be recovered from a modest number of observed outputs, after which every future and past value is determined. A password generator built on Math.random produces output that looks random to a strength meter and is reconstructible by anyone who can observe a few values from the same page.
One subtlety catches people who roll their own: reducing a random byte to an alphabet index with a plain modulo introduces bias, because 256 is not a multiple of 62. Reject and redraw the values that fall in the incomplete final block, as below.
The correct source is the platform's cryptographically secure random number generator, which on every modern platform is a thin wrapper over the operating system's entropy pool. In a browser or Node that is crypto.getRandomValues; in Python it is the secrets module; in Go it is crypto/rand; in Java it is SecureRandom. There is no performance reason to avoid them at password-generation scale.
const ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
function randomPassword(length) {
const n = ALPHABET.length; // 62
// Largest multiple of n that fits in a byte; values at or above
// this are discarded so every symbol stays equally likely.
const limit = 256 - (256 % n); // 248
const out = [];
const buf = new Uint8Array(1);
while (out.length < length) {
crypto.getRandomValues(buf);
if (buf[0] < limit) out.push(ALPHABET[buf[0] % n]);
}
return out.join("");
}
// 20 symbols from a 62-symbol alphabet
// = 20 * log2(62) = 119.1 bitsPassphrases: the same arithmetic, a different alphabet
A passphrase is not a weaker password with a friendly face. It is the identical calculation with words as the symbols. The EFF long wordlist contains 7776 entries, chosen so that each word can be selected with five dice rolls, which gives log2(7776) = 12.92 bits per word. Six words is 77.5 bits; seven is 90.5; ten is 129.
The entropy comes from the selection being random, not from the words being obscure. A phrase you thought of yourself is worth far less than its word count suggests, so accept the words the dice give you even when they are silly — the silliness is the entropy.
Passphrases are worth the extra characters precisely where a human has to reproduce the secret from memory or type it on a device with no password manager: a disk encryption passphrase, a password-manager master password, an SSH key passphrase, a recovery phrase. For the hundreds of site passwords you never type, a 20-character random string from a manager is strictly better because nobody has to remember it.
Why forced rotation makes passwords worse
Ninety-day expiry was security orthodoxy for two decades and is now explicitly recommended against by NIST, by the UK's NCSC and by Microsoft's own baseline guidance. The reasoning is worth understanding rather than just accepting, because the policy sounds prudent.
Rotation was meant to shorten the window in which a stolen password is useful. It does not, for a simple reason: an attacker who steals a credential uses it within minutes or hours, not within the eighty-nine remaining days of your cycle. Meanwhile the policy imposes a real cost on every user every quarter, and users respond rationally. Autumn2026! becomes Winter2027!. A single memorable base gets a counter appended. The password is written down. Helpdesk reset volume rises, and reset flows are themselves an attack surface.
The replacement is to rotate on evidence rather than on a calendar. Screen new passwords against a breach corpus so a known-compromised value cannot be set. Force a change when there is an actual signal: a breach notification, a detected compromise, a shared credential whose holder has left. And invest the effort saved in the controls that genuinely reduce credential risk, which are multi-factor authentication, rate limiting on authentication endpoints, and a slow password hash.
The password manager is the actual answer
Every recommendation above collapses into one practical arrangement: a password manager generating a long random string per site, protected by one strong passphrase and a second factor. This is not a convenience feature. It is what makes the advice achievable, because it removes the two constraints that produce bad passwords — having to remember them and having to type them.
It also eliminates credential stuffing as a class. Reuse is what turns a breach at one forgettable forum into an incident on your email and your bank, and unique per-site passwords sever that chain. A manager that fills by origin will also refuse to autofill your bank password on a lookalike domain, which is a phishing defence a human eye does not reliably provide.
About generating passwords in a web page
Our password generator runs in your browser and draws from crypto.getRandomValues, the same source a native application would use. The value is produced locally, is not transmitted, and is not logged. Those are real properties and we have implemented them deliberately.
We would still rather you used your password manager's built-in generator, and we would rather say that than optimise for time on page. The manager generates the password and stores it in the same step, so the secret never exists as selectable text in a browser tab, never enters your clipboard, and never appears in the clipboard history that your operating system and any sync service keep. A web generator necessarily involves a copy step, and the clipboard is a shared resource that other applications can read.
A browser-based generator is a good fit when you need a random value that is not a personal credential — a service account secret you are about to paste into a secret manager, a seed for a test fixture, a one-off token for a script, a throwaway value for a demo. It is a reasonable fallback when you are on a machine without your manager. It is the wrong place to create the master password that protects everything else; generate that one where it will live.
What to remember
- Compute strength as length × log2(alphabet size); aim for at least 80 bits for anything attackable offline, and 128 bits where it costs you nothing.
- Add characters rather than character classes — composition rules add almost no entropy and push humans into patterns crackers try first.
- A generator built on Math.random has no security value regardless of its output; only a platform CSPRNG such as crypto.getRandomValues counts.
- Rotate passwords on evidence of compromise, not on a schedule; calendar expiry measurably lowers the quality of the passwords people choose.
- Use a password manager for per-site secrets and a seven-word or longer generated passphrase for the few secrets you must type from memory.