ToolSink
Back to blog

Random Password Generators: The Actual Math Behind "Uncrackable"

ToolSink Team

Weak, reused passwords remain the most common way accounts get compromised — not because attacks have gotten cleverer, but because human-created passwords are predictable in ways that are trivial to exploit at scale.

Why human-created passwords fail specifically

Dictionary attacks test known words, phrases, and predictable substitutions (a@, e3) against login forms — this is why "P@ssw0rd123!" isn't meaningfully more secure than "password," despite looking more complex to a human eye.

Credential stuffing exploits password reuse: if your password from a minor forum breach matches your email or banking password, a bot will try that same combination everywhere within hours of a breach becoming public. This is why reuse — not weak individual passwords — is often the bigger practical risk.

The actual math behind password strength

Password strength is measured in bits of entropy — roughly, how many yes/no guesses an attacker needs in the worst case. It's calculated as:

entropy (bits) = log2(character_set_size ^ password_length)

For a 16-character password drawn from a 94-character set (upper, lower, digits, symbols):

import math
entropy_bits = math.log2(94 ** 16)
print(entropy_bits)  # ≈ 105 bits

For context: modern offline cracking rigs targeting a poorly-hashed password can attempt roughly 10^10–10^11 guesses per second. Against 105 bits of entropy (≈4×10^31 possible combinations), that's still on the order of 10^13+ years even at the faster end — which is why "impossible to crack in any practical timeframe" is a defensible claim for this specific case, though "impossible" in an absolute sense isn't quite right; it's astronomically improbable within any useful timeframe, not mathematically impossible.

The practical takeaway: length matters more than complexity tricks. A 20-character password using just lowercase letters (log2(26^20) ≈ 94 bits) is stronger than an 10-character password mixing every character type (log2(94^10) ≈ 66 bits) — length has a bigger multiplicative effect on entropy than character set size.

Why the randomness source matters, not just the output

A password generator is only as strong as its underlying randomness. This matters more than most people realize:

  • Math.random() in JavaScript is not cryptographically secure — it's a pseudo-random number generator designed for speed, not unpredictability, and its output can theoretically be predicted if an attacker knows enough about its internal state.
  • crypto.getRandomValues() (browser) or Python's secrets module are cryptographically secure — designed specifically so past output gives no advantage in predicting future output.
// Insecure - don't use for anything security-sensitive
const weakChar = Math.random();

// Cryptographically secure
const array = new Uint32Array(1);
crypto.getRandomValues(array);
import secrets
import string

alphabet = string.ascii_letters + string.digits + string.punctuation
password = ''.join(secrets.choice(alphabet) for _ in range(16))

If you're evaluating or building a password generator, this is the detail that actually determines whether the output is secure — not whether it looks sufficiently random to the eye.

A memorable alternative: Diceware-style passphrases

For passwords you must actually type or remember (a password manager's master password, most notably), a random string like k9#vP2$mLq7!zX5^bQ is secure but genuinely unmemorable. Diceware passphrases — several random dictionary words strung together (correct-horse-battery-staple-style) — can hit comparable entropy with far better memorability:

entropy (bits) = log2(wordlist_size ^ word_count)

Four words from a 7,776-word list (the standard Diceware wordlist) gives log2(7776^4) ≈ 51 bits — weaker than a 16-character random string, but six words gets you to ≈77 bits, which is solid for a master password you need to actually type and remember, versus a generated string you'll store in a manager anyway.

Practical setup

  • Use a password manager to generate and store unique, maximum-length random passwords per site — you never need to see or type most of them
  • Use a Diceware-style passphrase for the one master password you do need to remember
  • Enable 2FA/MFA everywhere it's offered — it protects you even if a password is compromised via phishing rather than brute force, which is a more common real-world attack path than cracking
  • Change a password only when actually needed — current guidance (including NIST's) has moved away from mandatory periodic rotation for strong, unique passwords; forced frequent changes tend to produce weaker, more predictable passwords in practice. Rotate immediately after a breach notification or suspicious activity, not on an arbitrary schedule.

For quickly generating a strong, unique password, ToolSink's Password Generator uses your browser's cryptographic random number source rather than a non-secure fallback — worth confirming for any password tool you use, not just this one.