Menu

Search toolsChangelog

to move to openDescribe the problem, not the tool

Generate a strong password

Draws a password from the browser's cryptographic random number generator, one character at a time, and reports the entropy of the generator that produced it rather than a guess at the strength of the string. The password is never written to the address bar, never stored and never sent anywhere.

Length buys more than variety does. Every extra character multiplies the work an attacker has to do.

a to z. Twenty-six characters.

A to Z. Twenty-six characters.

0 to 9. Ten characters.

The 28 ASCII punctuation marks, less the quote characters and the backslash, which break when pasted into a shell or a JSON file.

Your password
/8{/khP@dPOu9}s[npa+
Generated in this tab. It is not written to the address bar, not stored, and never sent anywhere.
Entropy, in bits
129.7
Characters to choose from
90
Average time to guess
174 quintillion years

Results are provided as-is, with no warranty of accuracy. The method and its sources are published below so you can check the working.

How it works

What this does

It draws a password one character at a time from the browser’s cryptographic random number generator, and then tells you how much randomness is actually in it. The second half is the part most generators get wrong, and it is the only part worth trusting.

A password’s strength is not a property of the string. It is a property of the process that produced it: how many equally likely passwords could have come out instead. Tr0ub4dor&3 looks strong and is not, because the process that produced it was a person substituting digits for letters in a dictionary word. Twenty characters drawn uniformly at random are strong even if one of them happens to spell something, because an attacker has no way to know that they did.

The method

Every byte comes from crypto.getRandomValues, defined in the Web Cryptography specification and backed by the operating system’s cryptographic generator. Math.random is not used anywhere, and there is a test that fails if it ever is. Math.random is a fast, non-cryptographic algorithm whose entire internal state can be recovered from a few of its own outputs, which means one password from it can be enough to predict the next.

Turning a random byte into a random character is where the second mistake usually happens. A byte is 0 to 255 and the alphabet here is 90 characters, and 256 is not a multiple of 90, so taking the remainder directly would return the first 76 characters of the alphabet three times per 256 bytes and the remaining 14 only twice - a 50% bias towards the front of the alphabet. Instead, any byte at or above 180, the largest whole multiple of 90, is thrown away and another is drawn. The cost is well under one extra byte per character; the benefit is that every character is exactly as likely as every other.

“At least one of every kind” is handled by rejection, not by repair. The common shortcut is to place one character of each required class at a fixed position and shuffle the rest, which produces a distribution that is not uniform and whose entropy nobody can state. This tool draws a whole candidate, checks it, and if a class is missing throws the candidate away and draws another. That samples the set of valid passwords uniformly, which means the entropy of the result is exactly the base-2 logarithm of how many valid passwords exist.

Counting them is inclusion and exclusion over the classes:

valid = SUM over subsets S of the classes of (-1)^|S| x (A - size(S))^L

  A = alphabet size, L = length, size(S) = characters in the classes in S

bits = log2(valid)
     = L x log2(A) + log2( SUM (-1)^|S| ((A - size(S)) / A)^L )

The second line is the one the code runs. Computed directly, the first is a difference between numbers around ten to the two hundred and fiftieth, which no floating-point number can hold; dividing through by A^L first makes every term a ratio between zero and one, and the sum stays accurate at any length.

Before you read on

Twenty characters drawn from a 90-character alphabet is 129.8371 bits. Then you tick at least one of every kind. What does that requirement cost?

  • It can and does: it rules out every string missing a class, so there are fewer valid passwords to be one of.

  • Yes — 129.6891 against 129.8371. Barely measurable.

  • That is the cost of the shortcut implementation, not of the rule. This tool does not use it.

0.148 bits, taking 129.8371 down to 129.6891. It is that small because 90.25% of twenty-character strings already contain all four kinds by chance, so the rule discards under a tenth of the possibilities. Put it next to what a single extra character buys — 6.49 bits, forty times as much — and the complexity policy your bank insists on turns out to be a rounding error, while the length limit it also imposes is the thing actually costing you. The tool gets that figure honestly by drawing whole candidates and discarding invalid ones, so the result is a uniform sample of the valid set and its entropy is exactly log2 of how many valid passwords exist.

Turning a random byte into a random character
  1. byte = 0 to 255,  alphabet = 90

    Every byte comes from crypto.getRandomValues. Math.random is not used anywhere, and a test fails if it ever is.

  2. character = byte % 90     <- wrong

    256 is not a multiple of 90, so this returns the first 76 characters three times per 256 bytes and the other 14 only twice. A 50% bias towards the front of the alphabet.

  3. if (byte >= 180) draw another

    180 is the largest whole multiple of 90 below 256. Throwing the remainder away is what makes the rest uniform.

  4. character = byte % 90

    Now every character is exactly as likely as every other. The cost is well under one extra byte per character.

A worked example

Twenty characters, all four kinds switched on, look-alikes allowed, at least one of every kind required.

Alphabet26 + 26 + 10 + 28 = 90
Unconstrained entropy20 x log2(90) = 129.8371 bits
Share of strings holding all four kinds90.25%
Entropy as generated129.6891 bits, shown as 129.7
Average guesses needed2 to the power of 128.6891
At 100 billion guesses a second174 quintillion years

So the rule that satisfies a website’s complexity policy costs 0.148 bits, which is a rounding error next to what it is often assumed to cost, and next to what a single extra character buys - 6.49 bits.

The same settings at other lengths:

LengthEntropyAverage time to guess
850.9 bits3 hours
1277.4 bits32.1 thousand years
16103.6 bits2.46 trillion years
20129.7 bits174 quintillion years
128831.0 bits2.2 x 10^231 years

These are the same numbers asserted in this tool’s test file, so if the formula ever changes without this page changing with it, the build fails.

What it does not do

It does not check the password against a breach corpus, and it does not need to: a password drawn from 90 characters at random has never appeared in one. It does not store anything, so there is no history and no way to recover a password you close the tab on - copy it into a password manager first. It does not know how the other end stores what you give it, which is the assumption that moves the time-to-guess figure the most: 100 billion guesses a second is right for a fast unsalted hash and wildly pessimistic for Argon2.

And it cannot help with the two ways passwords actually fail. Reuse turns one breach into many, and phishing hands over a 128-bit secret as readily as a four-digit one. Entropy is a lower bound on the effort of guessing, not a measure of how safe an account is.

How it is done

  1. Build the alphabet by joining the character classes that are switched on - 26 lower-case letters, 26 upper-case, 10 digits, and 28 ASCII punctuation marks with the two quote characters, the backtick and the backslash left out.
  2. If look-alike characters are excluded, remove capital i, lower-case L, one, the pipe, zero and capital O from that alphabet before anything else happens.
  3. Work out the rejection limit - the largest whole multiple of the alphabet size that is not greater than 256. For an alphabet of 90 that limit is 180.
  4. Draw one byte from crypto.getRandomValues. Discard it if it is at or above the limit, because folding it in with a remainder would make the first few characters of the alphabet more likely than the rest. Otherwise take the character at that byte's remainder.
  5. Repeat until the candidate is the requested length.
  6. If at least one of every kind is required and the candidate is missing a kind, throw the whole candidate away and draw a fresh one. Do not repair it by substituting a character, because that produces a distribution nobody can state the entropy of.
  7. Count the passwords the settings can produce, by inclusion and exclusion over the classes, and report the base-2 logarithm of that count as the entropy in bits.

What it assumes

  • The entropy figure describes the generator, not the string. A run of 20 lower-case letters is exactly as strong as any other draw of the same settings, because an attacker has no way of knowing it came out that way.
  • Requiring at least one of every kind reduces the number of passwords the generator can produce, so it reduces entropy. This tool reports the reduced figure; most generators report the larger one.
  • The time to guess assumes 100 billion guesses a second, which is an offline attack with commodity graphics hardware against a fast, unsalted hash. A password stored with bcrypt or Argon2 is many orders of magnitude slower to attack, and a rate-limited login is slower again.
  • The time shown is the average, not the worst case - half the search space, or two to the power of one less than the entropy.
  • Two quote characters, the backtick and the backslash are left out of the symbol set because they break when a password is pasted into a shell command or a JSON file. That costs about 0.06 bits per character.
  • Entropy says nothing about reuse, phishing or a breach at the other end. A perfect password used in two places is one password.

Common questions

Is the password sent anywhere, or stored?

No. It is generated by your browser and exists only in the page in front of you. There is no server to send it to - the whole site is static files. The settings travel in the address bar so a link reproduces the same options, but the password itself is deliberately kept out of it, so copying the link shares the recipe and not the secret.

Why is the entropy lower here than on other password sites?

Because "at least one of every kind" is switched on, and that rule shrinks the set of passwords the generator can produce. At 20 characters it rules out roughly one string in ten, which costs 0.15 bits. Most generators impose the rule and then report the figure for an unconstrained draw, which is slightly too high. Switch the rule off and the two figures agree.

Is eight characters enough?

No. Eight characters drawn from all 90 gives 50.9 bits, which is about three hours of guessing at 100 billion attempts a second. Twelve characters is 77.4 bits and around 32,000 years at the same rate; sixteen is 103.6 bits. Length is the only setting that changes the answer by orders of magnitude.

Does this use Math.random?

Never. Every byte comes from crypto.getRandomValues, which is the platform's cryptographic generator. Math.random is a fast non-cryptographic algorithm with a small internal state that can be recovered from a handful of its own outputs, so a password built from it can be reproduced by anyone who sees another one. There is a test in this tool's test file that fails if Math.random is ever called.

Should I turn on "leave out look-alike characters"?

Only for a password a person has to read and retype - a wi-fi passphrase on a router label, a temporary password read down a phone line. It removes I, l, 1, the pipe, 0 and O, which shrinks the alphabet from 90 to 84 and costs about 0.1 bits per character. For anything going straight into a password manager it is a pointless loss.

How long should a password actually be?

Long enough that the entropy is past 80 bits for an account that matters, which is 13 characters on these settings, and past 128 bits for a master password or an encryption key, which is 20. Both thresholds are asserted in this tool's test file. Beyond that the password stops being the weakest part of the system by a wide margin.

Sources

Method written and checked by Tessalor on Jul 30, 2026.