The Password That's Strong Everywhere Except Where It Matters
You generate a 24-character password with symbols. Excellent entropy. You paste it into the registration form and get:
Password must be 8-16 characters and contain only letters and numbers.
So you generate a shorter one. Then a different site rejects it because it lacks a symbol. Another silently truncates it at 20 characters without telling you — which you discover months later when the password you saved doesn't work.
Password generation is the easy part. Making a generated password survive contact with real systems is where the problems are.
Composition Rules Reduce Entropy
The requirement that a password contain at least one uppercase, one lowercase, one digit and one symbol feels like it strengthens passwords. Mathematically, it does the opposite.
Every constraint you add shrinks the space of allowed passwords. A rule requiring at least one digit eliminates every all-letter password from the possible set. Fewer possibilities means less entropy, not more.
The real-world effect is worse than the mathematical one, because humans respond to composition rules predictably:
password → Password1!
summer → Summer2026!
Capital at the start, digit and exclamation mark at the end. Attack tools model these transformations explicitly. A rule intended to increase variety produces a narrow, well-understood pattern.
This is why current guidance from bodies including NIST has moved away from composition requirements toward length minimums and breach-list checking. Length adds entropy unconditionally; composition rules add it only in theory.
For a randomly generated password, composition rules are simply an obstacle. The password already has whatever character variety the character set provides.
Calculating Entropy Honestly
For a truly random password:
entropy in bits = length × log₂(character set size)
Character set sizes:
| Set | Size | Bits per character |
|---|---|---|
| Digits only | 10 | 3.32 |
| Lowercase | 26 | 4.70 |
| Alphanumeric | 62 | 5.95 |
| Alphanumeric + common symbols | 94 | 6.55 |
So a 16-character alphanumeric password gives 16 × 5.95 ≈ 95 bits. A 12-character password from the full 94-character set gives 12 × 6.55 ≈ 79 bits.
Notice that the longer, simpler password is stronger than the shorter, more complex one. Length beats character set variety, and by a wide margin — each additional character adds a fixed number of bits, while expanding the character set adds diminishing returns.
The formula only holds for genuinely random passwords. A human-chosen password containing dictionary words has far less entropy than its length suggests, because the effective search space is the space of things humans choose, not the space of possible character strings.
Diceware-style passphrases are the exception: randomly selected words from a known list have calculable entropy — roughly 12.9 bits per word from a 7,776-word list. Six words gives about 77 bits, comparable to a 12-character random password and considerably easier to type.
Generating One That Works
The Password Generator produces random passwords:
- Set the length.
- Choose the character set.
- Generate and copy.
Practical defaults:
Length: 20+ where allowed. For anything stored in a password manager, longer costs you nothing. For something you'll type manually, 16 is a reasonable compromise.
Character set: alphanumeric plus a conservative symbol subset. Which brings us to the compatibility problem.
The Symbol Problem
Certain characters cause trouble in specific contexts, and generated passwords hit them regularly.
Shell contexts. $, `, \, !, ", ', *, ?, &, ;, |, (, ) all have meaning in shells. A password containing them in a script or environment variable needs careful quoting, and single-quoting doesn't protect against an embedded single quote.
URLs and connection strings. @, :, /, ?, #, %, & are structural in URIs. A database password containing @ in a connection string like postgres://user:pass@host/db breaks parsing unless percent-encoded.
Config files. # and ; start comments in many formats. = separates keys and values.
Regex and validation. Some systems validate passwords with regex and behave unexpectedly on metacharacters.
Space. Leading and trailing spaces get trimmed by forms and by some backends, silently changing the password.
A conservative symbol set that avoids most of this:
- _ . + = ~ ^ [ ] { }
Not exhaustive, but it steers around the worst offenders. For anything going into a config file, connection string, or environment variable, alphanumeric-only is the pragmatic choice — the entropy loss from dropping symbols is easily recovered by adding two or three characters.
Silent Truncation
The failure mode that causes real harm.
Some systems accept a long password at registration, silently truncate it to a maximum length, and store the truncated version. You save the full password in your manager. Login fails.
Worse: bcrypt has a 72-byte input limit. Input beyond that is ignored entirely. A 100-character password and a 200-character password with the same first 72 bytes hash identically. This is a property of bcrypt, not a bug, but systems that don't handle it can silently discard part of your password.
Note that it's 72 bytes, not characters. Multi-byte UTF-8 characters — accented letters, emoji, non-Latin scripts — consume 2–4 bytes each, so a password with accented characters hits the limit sooner than its character count suggests.
Practical defences:
- Test the login immediately after changing a password, in a fresh session
- Be cautious about passwords much longer than 64 characters on unfamiliar systems
- Avoid non-ASCII characters in passwords for systems you don't control — keyboard layout differences and encoding issues compound the byte-limit problem
Where Randomness Comes From
A password generator is only as good as its random number source.
Math.random() is not cryptographically secure. It's a pseudo-random generator designed for speed and statistical distribution, not unpredictability. Its internal state can potentially be inferred from observed outputs, which means passwords it generates may be predictable.
The correct source in a browser is crypto.getRandomValues():
const array = new Uint32Array(1);
crypto.getRandomValues(array);
In Node.js it's crypto.randomBytes(). In Python, the secrets module rather than random.
There's a second subtlety: modulo bias. Reducing a random number into a character set range with a naive modulo operation makes some characters slightly more likely than others when the range doesn't divide evenly.
// Biased
const index = randomValue % charset.length;
The correct approach rejects values that fall outside a clean multiple of the range and draws again. The bias is small, but it's an unnecessary weakness in something whose entire purpose is uniformity.
For anything genuinely sensitive, use a well-reviewed password manager's generator rather than any web tool — including this one. Browser-based generators are fine for learning and for low-stakes use; a password manager generates the password locally and stores it in the same operation, which removes the copy-paste step entirely.
What Actually Matters
Ranked by real-world impact:
1. Uniqueness. A unique password per site is more protective than any amount of complexity on a reused one. Credential stuffing — replaying credentials from one breach against other sites — is the dominant attack, and it defeats strong passwords completely if they're reused.
2. A password manager. Makes uniqueness practical. Without one, unique passwords across dozens of sites isn't achievable.
3. Multi-factor authentication. Turns a stolen password into an incomplete attack. Hardware keys and passkeys are phishing-resistant; SMS and TOTP can be phished in real time but are still substantially better than nothing.
4. Length. More valuable than character variety.
5. Breach checking. Knowing whether a password appears in a known breach corpus is more informative than any strength meter.
6. Character set complexity. Genuinely last. It matters least and gets the most attention.
Practical Tips
Generate 20+ characters for anything in a password manager. You'll never type it.
Use alphanumeric-only for config files, connection strings and environment variables. Add length to compensate.
Test login immediately after any password change, in a private window.
Never reuse a password, however strong.
Don't rotate passwords on a schedule without cause. Forced periodic rotation encourages predictable incremental changes and is no longer recommended by major guidance bodies.
Check the generator's randomness source if you're evaluating one for anything serious. Math.random() disqualifies it.
FAQ
Do composition rules make passwords stronger? No. They shrink the space of allowed passwords and push humans toward predictable patterns. Length minimums and breach checking are more effective.
How long should a password be? 16 characters minimum for something you type; 20 or more for anything stored in a manager. Length contributes more entropy per character added than complexity does.
Are symbols necessary? Not for entropy — adding characters achieves the same thing more reliably. They're worth avoiding in config files and connection strings where they cause parsing problems.
Why do some systems truncate passwords? Storage limits, or bcrypt's 72-byte input limit. Some do it silently, which is why testing login after a change matters.
Is Math.random() safe for generating passwords?
No. It isn't cryptographically secure. Use crypto.getRandomValues() in browsers or crypto.randomBytes() in Node.
Should I change passwords regularly? Only when there's a reason — a breach, suspected compromise, or shared access ending. Scheduled rotation without cause encourages weak incremental changes.
The Takeaway
Generating a strong password takes a second; making it work everywhere takes some judgement about character sets and length limits. Length beats complexity, alphanumeric-only avoids most compatibility problems, and none of it matters as much as using a different password on every site.
Generate strong random passwords free with the Password Generator at sadiqbd.com — no sign-up, instant results.