OpsecForge Hub/Password Generator
Web Crypto Randomness

Secure Password GeneratorRandom passwords generated in your browser with Web Crypto

Generated Password
Press Generate Password to create one.
16
8128
Password Strength
Strong
≈ 98 bits = 16 × log2(70)
Browser-only entropy via `crypto.getRandomValues`

How the strength estimate is calculated

For a password drawn uniformly at random, entropy in bits is the length times log2 of the number of possible characters. With all four sets ticked the pool is 26 + 26 + 10 + 8 = 70 symbols (the symbols are !@#$%^&*), so 16 characters give 16 × log2(70) = 16 × 6.129 = 98.07 bits. The figure under the strength label uses the same formula, so you can check it with a calculator.

Entropy by length and character set
SettingPool sizeEntropy (bits)
8 characters, all four sets7049.0
12 characters, all four sets7073.6
16 characters, letters and digits6295.3
16 characters, all four sets7098.1
16 characters, lowercase only2675.2
20 characters, all four sets70122.6
24 characters, all four sets70147.1

Treat the number as an upper bound. It applies only to characters picked at random, not to a password you typed or edited, and it says nothing about where the password is stored or reused. The Weak, Fair, Strong and Very strong bands (under 50, 50–79, 80–111, 112 and above) are this tool's own thresholds, not a published standard.

What the generator does

Randomness comes from crypto.getRandomValues, the browser's cryptographic random number generator, not Math.random. Turning a 32-bit draw into an index with a plain value % 70 would make the first 46 characters very slightly more likely, because 232 is not a multiple of 70 (the skew is about one part in 61 million). The tool avoids it by redrawing any value at or above the largest multiple of the pool size below 232:

Unbiased index (rejection sampling)
const limit = Math.floor(2 ** 32 / max) * max;
do { crypto.getRandomValues(buffer); } while (buffer[0] >= limit);
return buffer[0] % max;

Each ticked set contributes at least one character, then the rest are drawn from the merged pool and the result is shuffled. That rule excludes strings that miss a set, so the true ceiling is a little lower than the formula: for 16 characters it is 97.71 bits instead of 98.07. The point is only that the number on the page is an estimate, not an exact figure.

What NIST SP 800-63B-4 asks for

The current NIST password rules tell verifiers to require at least 15 characters when a password is the only authentication factor (8 if it is used only alongside another factor), to allow at least 64, and not to impose composition rules such as mixing character types. In practice: choose length over complexity, make each password unique, and keep them in a password manager. The character-set boxes are here because some sites still demand them.

The same thing in other languages

Python (secrets)
import secrets, string
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
"".join(secrets.choice(alphabet) for _ in range(16))
Node.js (crypto.randomInt avoids modulo bias)
import { randomInt } from 'node:crypto';
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*';
Array.from({ length: 16 }, () => alphabet[randomInt(alphabet.length)]).join('');

Questions

Is the password sent anywhere?
It is generated in this page and the tool does not transmit it. The page itself still loads normal site resources and aggregate analytics, which never include the generated value.
Share this: