TL;DR: Password strength is measured in entropy (bits of randomness). A 16-character lowercase password is actually stronger than an 8-character password with all the fancy symbols. Length beats complexity every time because entropy scales linearly with length but only logarithmically with character variety. Use a password manager, generate random passwords of 16+ characters, and enable two-factor authentication.
Everyone knows they should use strong passwords. But what does "strong" actually mean? Is P@$$w0rd! strong because it has symbols? (Spoiler: no.) Is correcthorsebatterystaple strong even though it is all lowercase? (Spoiler: yes, very.)
Let's dig into the actual math behind password security, because once you see the numbers, you will never look at passwords the same way again.
Password Strength Is Just Math (Specifically, Entropy)
In the world of security, password strength is measured in "bits of entropy" -- which is a fancy way of saying "how hard is this to guess?" More bits = harder to guess. The formula is beautifully simple:
Entropy (bits) = length * log2(pool_size)
Where:
- length = number of characters in your password
- pool_size = number of possible characters per position
Here are the common character pools:
- Lowercase only (a-z): 26 characters
- Mixed case (a-z, A-Z): 52 characters
- Mixed case + digits: 62 characters
- Everything including symbols: 95 characters
Now let's crunch some real numbers:
// 8 characters, lowercase only
8 * log2(26) = 37.6 bits
// 8 characters, full ASCII (letters + numbers + symbols)
8 * log2(95) = 52.6 bits
// 16 characters, lowercase only
16 * log2(26) = 75.2 bits
// 16 characters, full ASCII
16 * log2(95) = 105.1 bits
See that? A 16-character lowercase password (75.2 bits) absolutely crushes an 8-character password with every symbol on the keyboard (52.6 bits). Doubling the length is way more effective than quadrupling the character variety.
Why Length Wins Every Single Time
This is the most counterintuitive thing in password security. For decades, websites forced us to use short passwords crammed with symbols: P@$$w0rd!. Eight characters, 52.6 bits of entropy. Looks secure, right?
Meanwhile, correcthorsebatterystaple (25 lowercase characters) has 117.5 bits of entropy. That is astronomically stronger AND easier to remember. The famous xkcd comic about this was right all along.
The password "Tr0ub4dor&3" has about 28 bits of entropy (because humans are predictable with substitutions). "correct horse battery staple" has about 44 bits even as a passphrase... and you will actually remember it tomorrow morning.
The math behind this: entropy scales linearly with length (double the length, double the entropy) but only logarithmically with pool size (quadruple the pool, add just 2 bits per character). Length wins every time.
How Attackers Actually Crack Passwords
Understanding the attacks helps you understand why certain things matter:
Brute force: Try every possible combination. A modern GPU (like an RTX 4090) can test about 164 billion MD5 hashes per second. But against bcrypt with a proper cost factor? Only about 100 per second. The hashing algorithm matters just as much as the password itself.
Dictionary attacks: Try common words and known passwords from data breaches. The "rockyou.txt" wordlist has 14 million real passwords from a 2009 breach. If your password is a single dictionary word, it falls in seconds.
Rule-based attacks: Take dictionary words and apply common tricks. "password" becomes "P@ssword", "password1", "Password!". This is why letter-to-symbol substitutions (a to @, e to 3, o to 0) give you almost zero additional security. Attackers already know about those.
How Password Generators Work Under the Hood
A good password generator needs truly random numbers. In the browser, that means crypto.getRandomValues(), not Math.random(). Here is why that matters and how it works:
function generatePassword(length, options = {}) {
const {
uppercase = true, lowercase = true,
numbers = true, symbols = true
} = options;
let charset = '';
if (lowercase) charset += 'abcdefghijklmnopqrstuvwxyz';
if (uppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (numbers) charset += '0123456789';
if (symbols) charset += '!@#$%^&*()_+-=[]{}|;:,.<>?';
// Cryptographically secure randomness (not Math.random!)
const array = new Uint32Array(length);
crypto.getRandomValues(array);
let password = '';
for (let i = 0; i < length; i++) {
password += charset[array[i] % charset.length];
}
return password;
}
Never use Math.random() for password generation. It uses a deterministic algorithm -- if an attacker figures out the seed (sometimes based on timestamps), they can predict every "random" number. crypto.getRandomValues() uses your OS's entropy pool, seeded from hardware events like mouse movements and disk timing.
Making Sure All Character Types Show Up
Pure randomness might occasionally skip a character type -- generating a password without any uppercase letters even though the option was checked. Here is how to guarantee at least one of each:
function generateGuaranteed(length, options) {
const charsets = [];
if (options.lowercase) charsets.push('abcdefghijklmnopqrstuvwxyz');
if (options.uppercase) charsets.push('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
if (options.numbers) charsets.push('0123456789');
if (options.symbols) charsets.push('!@#$%^&*()_+-=[]{}|;:,.<>?');
// Guarantee one character from each selected type
let password = charsets.map(set => {
const idx = crypto.getRandomValues(new Uint32Array(1))[0] % set.length;
return set[idx];
});
// Fill the rest randomly from the combined pool
const allChars = charsets.join('');
const remaining = length - password.length;
const array = new Uint32Array(remaining);
crypto.getRandomValues(array);
for (let i = 0; i < remaining; i++) {
password.push(allChars[array[i] % allChars.length]);
}
// Shuffle so the guaranteed chars aren't always at the start
for (let i = password.length - 1; i > 0; i--) {
const j = crypto.getRandomValues(new Uint32Array(1))[0] % (i + 1);
[password[i], password[j]] = [password[j], password[i]];
}
return password.join('');
}
What You Should Actually Do in 2026
Based on current hardware and NIST guidelines, here is the practical advice:
- 12 characters minimum for any password. That is roughly 71 bits of entropy with a full character set.
- 16+ characters for important accounts (email, banking, your password manager's master password).
- 20+ characters if the service allows it and you use a password manager (so you do not need to remember it).
- Use a password manager. This is the single most impactful thing you can do. Unique, random, long passwords for every account.
- Enable two-factor authentication. Even the best password can be compromised through phishing. 2FA adds an independent second layer.
For your password manager's master password (the one password you DO need to remember), use a passphrase: 4-6 random words like "timber ocean violet pencil rocket dawn." Random words from a large list, not words you choose -- because humans are terrible at being random.
Try It Yourself
Generate a cryptographically secure random password with our free tool. Choose your length, character types, and copy the result with one click. Everything runs in your browser; no passwords are ever transmitted or stored.
Open Password Generator →