Where the randomness comes from
Every character is drawn from crypto.getRandomValues, the browser's cryptographically secure random source, which is seeded by the operating system. This is not the same thing as Math.random: that function is fast, deterministic from an internal seed, and completely unsuitable for anything secret — given enough output, its future values can be predicted.
There is a subtler mistake most generators also make, and this one avoids it. Turning a random 32-bit number into a number from 0 to 87 by taking the remainder introduces modulo bias, because 2³² does not divide evenly by 88 — the first few characters of the alphabet come up very slightly more often than the last few. The fix here is rejection sampling: any draw landing in the uneven remainder at the top of the range is discarded and a fresh one taken. The result is a genuinely uniform choice, and the same unbiased routine drives the Fisher–Yates shuffle that scrambles the final order.
That shuffle exists because of the "at least one of each" rule. When you tick lowercase, uppercase, digits and symbols, the generator takes one character from each selected set first, fills the rest from the combined pool, then shuffles — so a password always satisfies a site's composition requirements instead of failing validation one time in twenty.
Reading the entropy figure
Entropy in bits is the base-2 logarithm of how many passwords the generator could have produced with your current settings. Each bit doubles the search space. It is a property of the process, not of the string — which is why a password's strength survives being published in a manual, so long as the settings that produced it were random.
| Character sets enabled | Pool | Bits per character | 16 characters | 20 characters |
| Lowercase only | 26 | 4.70 | 75 bits | 94 bits |
| Lower + upper | 52 | 5.70 | 91 bits | 114 bits |
| Lower + upper + digits | 62 | 5.95 | 95 bits | 119 bits |
| All four (the default) | 88 | 6.46 | 103 bits | 129 bits |
| All four, ambiguous excluded | 82 | 6.36 | 102 bits | 127 bits |
The crack-time line beneath is deliberately pessimistic. It assumes an attacker who already holds your password hash offline and can test 100 billion guesses per second — a serious GPU rig against a fast, unsalted hash — and it reports the average, half the keyspace. Against a login form with rate limiting the number is meaningless, and against a password stored properly with bcrypt or Argon2 the attacker's rate collapses by orders of magnitude. It answers "what if the worst happens to the service I trusted", which is the only version of the question worth planning around.
Where the estimate is optimistic — and the passphrase caveat
The word list here is small. Passphrase entropy is the number of words times the bits each word carries, and this list holds 363 words — about 8.5 bits per word. Diceware's standard list holds 7,776 words and yields 12.9 bits each. The practical consequence is blunt: the default four-word passphrase is worth about 34 bits, which the meter on this page correctly labels Weak. Six words reaches 51 bits, and even the maximum of ten words lands near 85 bits — still below a 16-character random password. If you use passphrase mode, use six words minimum and keep the appended number on; if the account matters, use password mode.
The bits figure is an upper bound, not an exact count. Guaranteeing one character from each set slightly shrinks the true keyspace compared with drawing every character freely, but the displayed number is computed as length × log2(pool). The difference is small — well under a bit at usable lengths — but the figure rounds in the generator's favour rather than against it.
Excluding ambiguous characters costs entropy. Ticking that box removes I, l, 1, O, 0 and o, dropping the pool from 88 to 82. It is a fair trade when a password has to be read aloud or copied off a screen, and a waste when it is going straight into a password manager.
Local does not mean invisible. Nothing is transmitted and nothing is stored — reload the page and the password is gone forever. But it is on screen while you look at it and in your clipboard after you copy it, so generate it somewhere private, not on a shared screen or during a call. Clipboard history tools keep copies longer than you expect.
Practical advice
Length beats complexity, and uniqueness beats both. The overwhelming majority of account compromises come from a password reused on a service that was breached, not from someone brute-forcing a strong one. A 20-character random password used on one site only is far safer than a fiendish one used on five. That is a storage problem, not a generation problem — which is why a password manager is the other half of this tool.
Set the length by what the password protects. Twenty characters, the default here, is a sensible baseline for anything with money, mail or identity attached; sixteen is fine for ordinary accounts. Going above thirty adds nothing you will ever need against any attacker who exists. Resist trimming a generated password to fit a memorable shape — every hand edit invalidates the entropy figure, usually badly, because human edits are predictable.
If a site rejects your password, the usual culprit is a symbol its form dislikes. Put the symbols it does accept into the custom symbols field rather than switching symbols off entirely — you keep most of the pool. The bulk generator is there for seeding a batch of service accounts or device passwords in one pass.
Two related checks: the breach checker tells you whether a password you already use has appeared in a known data breach, and if you are storing hashes rather than passwords, the hash generator covers the common algorithms. More privacy and security utilities are on the developer tools page.