Generating Secure Passwords: Entropy, Length, and the Math That Matters
A modern consumer-grade GPU does about 10 billion SHA-256 hashes per second. That's 2³³ attempts/second. Below is what password length means under that workload, assuming a fast (non-bcrypt) hash:
| Random chars (94-set) | Bits of entropy | Time to crack |
|---|---|---|
| 8 chars | 52 | ~6 minutes |
| 10 chars | 65 | ~50 days |
| 12 chars | 79 | ~1,500 years |
| 14 chars | 93 | ~25 million years |
| 16 chars | 105 | ~100 billion years |
These numbers are why "8 characters with a number and a symbol" is laughable, while a 14-character random string blows past the heat-death of the sun. The thing your "complex" password is missing isn't symbols. It's bits.
Entropy in one paragraph
Entropy, in this context, is a measure of unpredictability. It's expressed in bits: each bit represents a doubling of the search space an attacker has to brute-force.
- 10 bits of entropy = 1,024 possibilities
- 20 bits = ~1 million
- 40 bits = ~1 trillion
- 80 bits = ~10²⁴
A modern GPU can attempt about 10 billion fast hashes per second (SHA-256). 10 billion is roughly 2^33 attempts per second. So:
- 40-bit password: cracked in seconds
- 60-bit password: cracked in days
- 80-bit password: cracked in centuries
For password storage with bcrypt or argon2 (which are deliberately slow), the same passwords are 10⁵ to 10⁷ times harder to crack. Slow hashing buys you a lot.
The target for 2026: at least 80 bits of entropy for general accounts, 100+ bits for high-value accounts (email, banking, password manager master).
How to count entropy
For a truly random password drawn from a known character set:
entropy = length × log2(charset size)
| Charset | Size | Bits per character |
|---|---|---|
| Lowercase only | 26 | 4.7 |
| Lower + upper | 52 | 5.7 |
| Lower + upper + digits | 62 | 6.0 |
| Lower + upper + digits + 32 symbols | 94 | 6.6 |
So a truly random 12-character mixed-case password with digits has 12 × 5.95 ≈ 71 bits. That's borderline. 14 chars: 83 bits. 16 chars: 95 bits.
Numbers above assume random characters. If you used a base word and modified it, your real entropy is much lower.
Why your "complex" password is weak
Take P@ssw0rd! — 9 characters, mixed case, digit, symbol, "satisfies all requirements." Real entropy:
- Choice of base word: maybe 2,000 common words = 11 bits
- Capitalization pattern: typically 3-5 patterns tried = 2 bits
@fora,0forois one of ~10 known substitutions = 4 bits- Trailing
!vs1vs123= 4 bits
Total: ~21 bits. A few hours on a GPU.
Password crackers know all the common transformations. They use word lists, leet rules, and prefix/suffix dictionaries. "Complex-looking" doesn't beat any of that. Length and randomness do.
Two ways to generate strong passwords
1. Random characters (best for password manager)
3kF9!nW#mZ4p
12 characters, full charset, ~79 bits. Unmemorizable but you don't need to memorize it, you put it in 1Password / Bitwarden / KeePassXC and never type it again.
Password Generator does exactly this in your browser. Choose length and charset, get a high-entropy password, copy.
2. Diceware passphrases (best for memorable passwords)
correct horse battery staple
Famous from xkcd #936. Four random words from a list of ~7,776 (the Diceware list).
4 × log2(7776) = 51.7 bits
51.7 bits is less than the 12-char random above. You need 6 words for 78 bits, or 7 words for 90 bits. The win is memorability, not bit-count.
Use diceware when:
- You'll need to type it (master password, SSH key passphrase, disk encryption)
- You can't (or won't) memorize random characters
For everything else, use a password manager and random passwords.
What "true randomness" means
The entropy math only holds if the password is generated by a cryptographically secure random number generator (CSPRNG):
| Source | CSPRNG? |
|---|---|
Math.random() (JS) |
❌ No |
Random() (Python) |
❌ No |
crypto.randomBytes() (Node) |
✅ Yes |
secrets.token_* (Python) |
✅ Yes |
crypto.getRandomValues() (Browser) |
✅ Yes |
/dev/urandom (Linux) |
✅ Yes |
Generators that aren't cryptographically secure are predictable to an attacker who knows the seed. Use secrets in Python, crypto in Node, getRandomValues in browsers. Not Math.random().
Password Generator uses crypto.getRandomValues, your password is generated by your browser's secure RNG and never sent anywhere.
Length recommendations for 2026
| Account type | Recommended entropy | Random chars (94-set) |
|---|---|---|
| Throwaway account | 60 bits | 10 chars |
| Regular account | 80 bits | 13 chars |
| Email, banking | 100 bits | 16 chars |
| Password manager master | 120+ bits | 7 diceware words |
| SSH key passphrase | 100 bits | 7 diceware words or 16 chars |
| Cryptocurrency wallet | 128+ bits | 24 BIP-39 words |
Don't go below 80 bits for anything that matters. Don't bother going above 128 bits for normal accounts; the bottleneck shifts to other attack vectors (phishing, OS compromise, etc.).
What about password requirements?
Most password policies are useless or harmful:
- "Must contain a digit and a symbol" → users add
1!to a base word. Trivial to crack. - "Cannot reuse last 5 passwords" → users add 1, 2, 3 to the end.
- "Must change every 90 days" → NIST removed this in 2017 because it leads to weaker passwords.
- "Cannot start with a digit" → reduces entropy. No security benefit.
- "Maximum length 16" → forces users into the cracking-feasible zone.
Modern guidance (NIST SP 800-63B, OWASP):
- Minimum 8 characters, encourage 14+
- Don't impose composition rules
- Check against a list of compromised passwords (e.g., HaveIBeenPwned)
- Don't force periodic changes
- Allow long passwords (up to 64+ chars)
- Allow all printable characters including spaces
Password reuse is the actual problem
Most password breaches don't crack the hash. They reuse credentials from other breaches. If you use P@ssw0rd! on Reddit and Reddit gets breached, attackers try P@ssw0rd! on Gmail.
Use a password manager. Generate a unique password per site. The math of entropy stops mattering, what matters is that an attacker who breaches one site can't use those credentials elsewhere.
In 2026, the password manager landscape:
- Free, open source: Bitwarden, KeePassXC
- Commercial: 1Password, Dashlane
- Browser-built-in: Chrome / Firefox / Safari password managers (decent, less feature-rich)
Pick one. The differences between them matter less than the difference between using one and not.
When passwords aren't enough
For any account that matters, password + 2FA. The password generates 80 bits. The 2FA TOTP adds 20 bits per 30-second window, but more importantly, an attacker needs both the password AND the second factor.
WebAuthn / passkeys are even better, public-key cryptography, phishing-proof, no password to leak. As of 2026, most major sites support them. If your bank / email / GitHub offer passkeys, switch.
Recommended workflow
- Use a password manager for every account. Don't memorize passwords (except the master).
- Generate with Password Generator or your manager. 16 chars, full charset, for 95+ bits.
- Master password: 7-word diceware passphrase. Memorable, ~90 bits.
- Enable 2FA on every account that supports it. Use TOTP / 2FA Generator for testing the codes.
- Migrate to passkeys wherever supported.
The mistake to avoid: using "complex" password rules to compensate for short length. 8 chars with all the rules is weaker than 14 chars random lowercase. Length and randomness, full stop.
Related tools on DevTools Online:
- Password Generator, random passwords with selectable charset
- TOTP / 2FA Generator, for 2FA setup
- Hash Generator, see what hashing actually does to a password
- bcrypt, for storing passwords (server-side)