---
title: "Password Generator"
description: "Cryptographically secure password generator with adjustable length and character classes. Runs in your browser."
url: https://sade.dev/en/tools/password-generator/
lang: en
author: "Muhammet Şafak"
published: 2026-05-19
updated: 2026-08-30
section: Tool
tags: ["password","security","crypto"]
---

# Password Generator

> Cryptographically secure password generator with adjustable length and character classes. Runs in your browser.

Random passwords generated with `crypto.getRandomValues` — **cryptographically secure**. Length,
character classes, and filters are adjustable. Nothing is sent to a server.

## Why isn't Math.random() enough?

JavaScript's `Math.random()` function is **not cryptographically secure**. V8 and other
engines typically use a fast but predictable algorithm like `xorshift128+`. Anyone who observes
enough output can predict the next "random" values.

For password generation, `crypto.getRandomValues` is mandatory — the values come from the browser's
own CSPRNG, seeded from an operating system entropy source (`/dev/urandom` on Linux, `getentropy()`
in Chromium and CommonCrypto's `CCRandomGenerateBytes` in WebKit on macOS, `CNG` on Windows).

## Why does entropy matter?

Password strength is measured in **entropy** (in bits):

```
entropy = length × log₂(alphabet_size)
```

Examples:

| Length | Alphabet | Entropy |
|---|---|---|
| 8 | 26 (lowercase only) | ~38 bits — **weak** |
| 12 | 62 (a-z A-Z 0-9) | ~71 bits — strong |
| 16 | 94 (printable ASCII, excluding space) | ~105 bits — very strong |
| 20 | 94 | ~131 bits |

The last two rows are a general ASCII reference: this tool's widest alphabet is 88 characters
(26 + 26 + 10 + 26 symbols), so it cannot produce them — 20 characters top out at ~129 bits here.

Practical thresholds:

- **< 40 bits:** weak — brute-forced within hours by modern GPUs.
- **40–60 bits:** medium — the band the tool itself labels "Medium"; against a fast hash a single
  GPU covers the low end in hours and the top in weeks.
- **60–80 bits:** strong — out of reach against a slow hash (bcrypt, Argon2); against a fast hash
  like MD5 a single GPU clears the lower end in weeks, so "specialized hardware and years" holds
  only for the upper end.
- **> 80 bits:** very strong — holds up even against the next decade's brute-force capacity.

## Length vs complexity

The most efficient way to increase a password's strength is to **increase length, not character variety**.
20 lowercase characters (~94 bits) are far stronger than 8 characters with symbols (~52 bits).

> Adding a single character multiplies the odds by the size of the alphabet; widening the alphabet
> multiplies them by `(b₂/b)^length` — a gain of `length × log₂(b₂/b)` bits, proportional to length
> rather than a fixed multiplier. At this tool's default of 20 characters, adding the symbol class
> (62 → 88) is worth ×1101, more than the ×62 of one extra character.

The length-first advice still holds — not because the extra classes gain little, but because forced
character classes push people toward predictable patterns, which is why NIST dropped composition
rules.

## Modulo bias

If a naive "random 8-bit number → character" mapping is done with `byte % charset.length`, some
characters appear **more often** than others. For example: if `charset.length = 62`, the 256 numbers
from 0–255 don't divide evenly by 62 (256 % 62 = 8). Five byte values land on each of the first 8
characters and only four on the other 54, so those 8 get picked 25% more often.

This tool uses **rejection sampling**: bytes at or above `maxValid = 256 - (256 % setSize)` are
discarded. The result: a perfectly uniform distribution where every character is picked with equal probability.

## "Exclude ambiguous characters"

If the password will be written on paper or read aloud, `0/O` and `1/l/I/|` are hard to tell apart.
This option removes those characters. **Entropy drops** — a deliberate tradeoff for practicality.

## "Shell-safe"

If the generated password will be written into `bash`, a SQL connection string, a URL, or a `.env`
file, characters that need escaping (`$`, `` ` ``, `"`, `'`, `\`, `;`, `|`, `&`, `<`, `>`, `(`, `)`)
cause trouble. This filter removes them — enough to skip escaping in a shell, but not in a URL: the
RFC 3986 reserved characters (`!`, `@`, `#`, `*`, `+`, `=`, `[`, `]`, `:`, `,`, `?`, `/`) and `%`
itself survive the filter and still need percent-encoding.

## What this tool is *not* for

- **Production secret management.** Save the generated password into a password manager (1Password,
  Bitwarden, KeePassXC) or a secret store (Vault, AWS Secrets Manager) right away — don't leave it here.
- **Choosing a master password.** For a master password, a **diceware-style passphrase** is better:
  memorable + high entropy. (That's on the V1.2 roadmap for this tool.)
- **Generating shared secrets.** In scenarios where both parties must know the same secret, a key
  exchange protocol (Diffie-Hellman) — with a key derivation function such as HKDF (RFC 5869) run
  over its output — is a better fit.

## Privacy

This tool runs **entirely in your browser**. Generated passwords are never sent to a server. Even so:

- If you copy the generated password to the clipboard, other applications can access it.
- Some browser extensions can read DOM content.
- If the password is visible during screen sharing, it can be recorded.

For sensitive accounts: generate, copy, paste into your password manager, **clear the clipboard**.
