Skip to content
Spellkit

How a Password Generator Actually Picks Random Characters

The security of a generated password depends entirely on where its randomness comes from — and Math.random() is the wrong answer.

A password generator's whole job is one thing: pick characters unpredictably. How it does that — specifically, where the randomness comes from — determines whether the output is actually secure or only looks like it.

Not all "random" is equal

Software has (at least) two categories of random number generator, and they're not interchangeable:

  • Pseudorandom (PRNG) — deterministic algorithms that produce number sequences which look statistically random but are fully determined by a starting seed. Math.random() in JavaScript is a PRNG. Given the same seed, it produces the exact same sequence every time — useful for reproducible simulations or shuffling a game board, but that determinism is exactly the property you don't want in a password.
  • Cryptographically secure (CSPRNG) — designed so that even if an attacker sees a large number of prior outputs, they gain no practical ability to predict the next one. crypto.getRandomValues() (browser) and crypto.randomBytes() (Node) are CSPRNGs, typically seeded from OS-level entropy sources (hardware noise, timing jitter, etc.).

A password generator built on Math.random() produces output that looks fine to a human eye but is a fundamentally weaker random source — some implementations have had small enough internal state that their output was predictable after observing enough samples. A generator worth trusting is built on a CSPRNG, full stop.

Length beats complexity rules

A common but outdated instinct is "require at least one uppercase, one number, one symbol." This helps far less than it seems to, because it constrains the search space in predictable ways attackers already account for (most crackers assume a capital letter first, a digit or symbol last). What actually determines how hard a password is to brute-force is entropy: the character set size, raised to the power of the length.

A 20-character password from lowercase letters only (26 choices per character) has more possible combinations than an 8-character password using all four character classes (~94 choices per character) — because entropy grows exponentially with length but only linearly-ish with alphabet size. In other words, length is doing almost all of the real work.

What "avoid ambiguous characters" is actually for

An option like "exclude 0/O/l/1/I" has nothing to do with security — it trades a small amount of entropy for human readability, useful specifically for passwords you'll be typing from a printed sheet or reading over the phone, where those characters are visually confusable. If the password will only ever be copy-pasted, there's no reason to enable it.

Why you shouldn't reuse a "good" password

Even a properly-generated, high-entropy password is only as safe as the one place it's used. If it's reused across sites and any one of those sites suffers a data breach, the password itself was never the weak point — the reuse was. A password manager generating and storing a unique password per site is what actually neutralizes this, regardless of how the passwords were generated.

Spellkit's Password Generator uses the browser's CSPRNG and runs entirely client-side — the generated password is never transmitted anywhere, including to Spellkit's own servers.