Password entropy and crack time
The formula is one line and it is exact for machine-generated strings. Everything interesting is in the conditions it needs and in what happens after the password is stored.
Updated 2026-09-05
The formula, and the two conditions it needs
For a string of L characters drawn independently and uniformly from an alphabet of N distinct symbols, the entropy is H = L x log2(N) bits. A sixteen-character alphanumeric string is 16 x log2(62) = 95.27 bits. A twenty-character password over the 94 printable ASCII characters is 131.09 bits. Thirty-two hexadecimal characters are exactly 128 bits, because log2(16) is exactly 4.
The formula is a compression of two separate claims and both have to hold. H equals the base-two logarithm of the size of the string space, which requires the distribution over that space to be uniform. And the size of the space is N^L, which requires the characters to be independent of one another. Break uniformity and you have modulo bias. Break independence and you have a composition rule. Either one makes the formula overstate the truth, and the overstatement is always in the direction that flatters the tool.
This is also why the formula is honest for machine-generated strings and dishonest for human-chosen ones. NIST moved away from entropy scoring in its password guidance precisely because estimating the entropy of a password a person invented is guesswork. That critique is correct and it does not apply here. When a CSPRNG picks each character uniformly from a known alphabet, L x log2(N) is not an estimate. It is the exact value.
| N | Alphabet | log2(N) | Exact? |
|---|---|---|---|
| 10 | digits 0-9 | 3.321928 | no |
| 16 | hex 0-9a-f | 4.000000 | exact |
| 26 | letters a-z | 4.700440 | no |
| 32 | Crockford or RFC 4648 base32 | 5.000000 | exact |
| 36 | a-z0-9, base36 | 5.169925 | no |
| 49 | nanoid nolookalikes | 5.614710 | no |
| 52 | a-zA-Z | 5.700440 | no |
| 62 | alphanumeric | 5.954196 | no |
| 64 | base64url, nanoid default | 6.000000 | exact |
| 74 | alphanumeric plus 12 safe symbols | 6.209453 | no |
| 94 | printable ASCII except space | 6.554589 | no |
log2(52) = log2(26) + 1 exactly, so adding uppercase to a lowercase alphabet buys exactly one bit per character and never more. At sixteen characters that is sixteen bits, which is real but far less than the interface implies when it colours the meter green.
Every option in the generator that reduces the number
Options that feel like they make a password stronger usually make it weaker, because most of them constrain the space rather than expand it. The honest thing for a generator to do is to show the corrected figure rather than the headline one.
A must-include-one-of-each-class rule breaks independence. The correct entropy is L x log2(N) plus log2 of the fraction of strings that satisfy the rule, computed by inclusion and exclusion over the class subsets. The cost is usually small, between roughly 0.01 and 1.1 bits for realistic configurations. It matters much more how the rule is implemented. Generating a string and then overwriting position zero with an uppercase letter and position one with a digit is not uniform and creates a positional pattern that reduces min-entropy further. Generating the whole string, testing it, and discarding and regenerating on failure is exactly uniform over the valid set. The expected number of attempts is 2.17 for eight characters over 94 symbols with four required classes, and 1.064 for sixteen characters over 62. Correctness here costs one extra generation, occasionally.
A no-repeated-characters rule is the expensive one and it is the one users switch on most confidently. The entropy becomes the sum of log2(N - i) over the string, and the loss is 3.059 bits at sixteen characters over 62 symbols, 14.225 bits at thirty-two characters over 62, and 15.119 bits at twenty characters over 26. A generator that offers this toggle and does not adjust the displayed entropy is lying by roughly two characters' worth.
Excluding ambiguous characters is the one that behaves well. It shrinks the alphabet, and that is all it does, so the formula still applies with the smaller N. Going from 62 characters to the 49-character nolookalikes set costs exactly 0.3395 bits per character, which is 5.70%, and is recovered by one extra character per 16.5. A sixteen-character alphanumeric string is 95.267 bits; a seventeen-character nolookalikes string is 95.450. Show people that trade instead of hiding it.
| Option | What it breaks | Typical cost | Warn the user? |
|---|---|---|---|
| Modulo bias | uniformity | 4.418 bits at 16 characters over 62 | It is a bug. Do not have it. |
| Must include each class | independence | 0.01 to 1.1 bits | Only when it exceeds 0.05 bits |
| No repeated characters | independence | 3.06 bits at L=16, 14.23 at L=32, both over 62 | Yes, loudly |
| Exclude ambiguous characters | nothing | 5.70% at 62 down to 49 | Informational |
Crack time is a property of the hash, not of the password
Entropy tells you how many candidates an attacker has to try. It says nothing at all about how long one try takes, and that second number varies by seven orders of magnitude across storage schemes in production today.
The rates below are measured, from the Chick3nman benchmark set for hashcat v6.2.6-851 on a single NVIDIA RTX 5090 with optimised kernels. They are a specific tool on a specific card at a specific moment, and they should be read that way rather than as a law of nature.
| Mode | Algorithm | Rate |
|---|---|---|
| 0 | MD5 | 220.6 GH/s |
| 1000 | NTLM | 340.1 GH/s |
| 1400 | SHA2-256 | 28.35 GH/s |
| 3200 | bcrypt, cost 5 | 304.8 kH/s |
| 8900 | scrypt, N=16384 | 7,760 H/s |
The same password, six different answers
Expected time to find a uniformly random secret is 2^(H-1) divided by the guess rate, since on average the attacker searches half the space. Applying that to the measured rates gives the table below. The 100,000-GPU column is a well-funded adversary, not a hobbyist, and is included so the numbers do not read as complacent.
Read across the 64-bit row. The same secret is seven minutes on a 100,000-GPU farm against MD5, 1.3 years against MD5 on one card, ten years against SHA2-256, and 959,000 years against bcrypt at cost 5. Against bcrypt at cost 12 it is about 123 million years, which is an extrapolation from the measured cost-5 rate using the algorithm's defined work doubling, 304,800 divided by 128 giving roughly 2,381 hashes per second. That figure is labelled as extrapolated because it is.
The general form of this is worth stating as a rule. The ratio between the MD5 rate and the bcrypt cost-12 rate is 220.6 x 10^9 over 2,381, which is 2^26.47. So a 128-bit secret stored as an unsalted MD5 hash costs an attacker exactly as much work as a 101.5-bit secret stored under bcrypt at cost 12. Choosing a longer password is one lever. Choosing a slower hash is a bigger one, and it is not the user's to pull.
| Entropy | MD5, 1 GPU | SHA2-256, 1 GPU | bcrypt cost 5 | scrypt N=16384 | MD5, 100k GPUs |
|---|---|---|---|---|---|
| 40 bits | 2.5 s | 19 s | 21 days | 2.2 years | - |
| 56 bits | 1.9 days | 15 days | 3,750 years | 147,000 years | - |
| 64 bits | 1.3 years | 10 years | 959,000 years | 37.7 million years | 7 minutes |
| 80 bits | 86,800 years | 676,000 years | 62.8 billion years | 2.5 trillion years | 317 days |
| 112 bits | 373 trillion years | 2,900 trillion years | - | - | 3.7 billion years |
| 128 bits | 2.4 x 10^7 trillion years | - | - | - | 244 trillion years |
Argon2id is deliberately absent. hashcat 6.2.6 predates Argon2 support and there is no measured rate to quote, so any number here would be invented. Reason about it from its memory cost instead: an Argon2id configuration using 64 MiB per guess bounds the attacker by memory capacity and bandwidth rather than by how many arithmetic units the card has, which is exactly why it exists.
Where the thresholds come from
Strength labels are worth almost nothing unless each boundary is anchored to something you can cite. Ours are anchored to NIST SP 800-63B-4 and to the rate table above, and the number is always shown next to the label because the number is the part that carries information.
Below 32 bits is broken: 2^31 MD5 guesses is about ten milliseconds on one card. A six-digit one-time code sits at 19.93 bits and belongs in this band, which is correct rather than embarrassing, because such codes are safe only in combination with rate limiting and a short lifetime. From 32 to 63 bits is weak, because NIST requires that a secret below 64 bits be rate-limited. From 64 to 79 is moderate, 64 being NIST's floor for a secret that stands on its own without rate limiting. From 80 to 111 is strong. From 112 to 127 is very strong, 112 bits being the minimum random bit generator security strength NIST mandates through SP 800-131A. At 128 bits and above the bar stops, because it matches AES-128 and additional bits buy nothing against brute force.
One last note on composition rules, since a generator has to take a position. NIST SP 800-63B-4 states that verifiers SHALL require at least 15 characters for a password used as a single factor, and that other composition requirements SHALL NOT be imposed. PCI DSS v4.0.1 requirement 8.3.6 goes the other way and asks for numeric and alphabetic characters at a minimum of twelve. Those two are in direct conflict, and 6.0% of uniform sixteen-character alphanumeric strings contain no digit at all and would fail the PCI check. If you need a PCI-compliant mode, it has to enforce the constraint by whole-string rejection rather than hope, and it has to show you the corrected entropy afterwards.
Questions
How many bits do I actually need?
For anything long-lived that is not rate-limited, 128 bits is the target and there is no benefit above it. For a short-lived reset link, 64 to 80 is defensible. Below 64 bits NIST requires rate limiting, which means you are relying on your infrastructure rather than on the secret. A twenty-character password over 94 symbols is 131 bits, and a 22-character base64url token is exactly 132.
Does adding a symbol make my password much stronger?
It expands the alphabet, which is worth about 0.26 bits per character going from 62 symbols to 74. Over sixteen characters that is roughly four bits, or two thirds of one extra character. Adding one more character is usually worth more than adding a whole symbol class, and it will not break the site you are pasting it into.
Why does a password checker give my generated password a different score?
Most checkers estimate entropy from the string itself, using patterns, dictionaries and character classes, because they are designed for passwords a human chose. Applied to a uniformly random string that method is a guess about a value that is already known exactly. Entropy is a property of the process that generated the string, not of the string.
Is a longer password better than a bigger alphabet?
Almost always, for practical reasons. Both add bits, but length has no compatibility cost and symbols do: a field that rejects certain punctuation, a shell that interprets it, a CSV export where a leading equals sign becomes a formula. Sixteen alphanumeric characters is 95.27 bits and pastes everywhere.
How long would it take to crack my 12-character password?
The question cannot be answered without knowing the hash. Twelve random alphanumeric characters is 71.45 bits. That is about 230 years against unsalted MD5 on one RTX 5090 at the rate in the table above, and geological against bcrypt on the same card. If the password was not machine-generated, the entropy figure does not apply at all and the honest answer is much shorter.