Password Entropy: Why Length Beats Complexity Every Time

Ask a developer to generate a strong password and most will reach for a jumble of symbols: P@ssw0rd! or something similarly unmemorable. The intuition is that complexity is what makes a password hard to crack. It is not. Length is. This post works through the actual math so you can stop guessing and start sizing passwords against a threat model.

The only metric that matters: entropy

Password strength is measured in bits of entropy — the base-2 logarithm of the size of the space an attacker must search. For a password of length L drawn uniformly from an alphabet of N characters:

H = L * log2(N) 

The exponent is the key. Every additional bit doubles the work of a brute-force attack. Every additional character from a 26-letter alphabet adds about log2(26) = 4.7 bits. Complexity adds a smaller alphabet boost; length multiplies it.

Worked example: complexity vs length

Compare two passwords:

  • 8 chars, all 94 printable ASCII: H = 8 * log2(94) = 8 * 6.55 = 52.4 bits
  • 20 chars, lowercase only (26): H = 20 * log2(26) = 20 * 4.70 = 94.0 bits

The long, all-lowercase passphrase has roughly 2^41 times more search space than the short "complex" one. That is the entire argument. A 20-character phrase of ordinary words beats an 8-character symbol soup by an absurd margin, and it is easier to remember.

Where the model breaks down

The formula assumes characters are chosen independently and uniformly. Real passwords violate this in three ways:

  1. Humans are not random. "correct horse battery staple" is 25 characters but its entropy is nowhere near 25 × 4.7 bits — it is a handful of dictionary words, and dictionary attacks exploit exactly that.
  2. Password reuse collapses everything. If one site leaks, every site using that credential is compromised. Entropy per password does not help if the same password is used everywhere.
  3. Generated ≠ random. A generator that uses Math.random() instead of a cryptographically secure source (CSPRNG) produces output that looks random but is predictable. Always use crypto.getRandomValues in the browser or secrets in Python.

This is why the practical advice is: use a generator with a CSPRNG, make it long (16+ characters), and use a unique one per site — ideally stored in a password manager so you never have to remember any of them.

A quick entropy reference

Alphabet Bits per character 12 chars 16 chars 20 chars
lowercase (26) 4.70 56 75 94
lower+upper (52) 5.70 68 91 114
alnum (62) 5.95 71 95 119
all printable (94) 6.55 79 105 131

Note how the 16-character "lowercase only" row (75 bits) already clears the short "all printable" row (79 bits at 12 chars is higher — but at 8 chars it is only 52). At a fixed length, a bigger alphabet helps; across lengths, adding characters wins faster.

Tooling

When you need to check the exact entropy of a candidate or produce a CSPRNG-backed password with configurable length and character sets, I built a small client-side tool: the Random Password Generator. It runs entirely in the browser, exposes length and character-type controls, can exclude ambiguous characters (0/O, 1/l), and shows the resulting entropy so you can see the tradeoff rather than guess. No passwords are transmitted anywhere.

Bottom line

  • Maximize length first, alphabet size second.
  • Use a CSPRNG, never Math.random().
  • One unique password per site, via a manager.
  • 16+ characters is a sane default for anything important.

Entropy is just arithmetic. Once you internalize H = L * log2(N), the "complex vs long" debate stops being a matter of opinion.