Methodology & Accuracy
Every generator on this site is a thin interface over one small, pure, automatically tested drawing engine. This page documents how a letter actually gets chosen — where the randomness comes from, how bytes become letters without bias, how pools are built — and what the site deliberately does not do.
Where the randomness comes from
Draws use the Web Crypto API (crypto.getRandomValues), the same
operating-system-backed source browsers use for encryption keys and secure tokens. The engine
never touches Math.random(), which is a convenience generator with no uniformity or
unpredictability guarantees. "Cryptographically uniform" on this site means exactly this:
cryptographic-quality input bytes, mapped to letters by a construction that provably preserves
uniformity.
Rejection sampling, in plain language
A random byte holds 256 equally likely values, but a letter pool holds, say, 26. The tempting shortcut — divide by 26 and keep the remainder — is biased: 256 is not a multiple of 26, so the remainders 0–21 occur ten times among 256 byte values while 22–25 occur only nine, making A–V about 11% more likely than W–Z. This engine instead does what dice players do when a roll doesn’t fit: reroll. It keeps only the minimal bits needed to cover the pool (5 bits for 26 letters, values 0–31), and if the value lands at or beyond the pool size — 26 through 31 — it is thrown away entirely and a fresh value is drawn. Nothing wraps around, so every letter keeps exactly probability 1/26. Rejection wastes a few draws (never more than half, so on average fewer than two per letter) and buys exactness — the uniformity claim rests on this construction, not on statistical testing after the fact.
How pools are built
A draw's pool is composed in a fixed order: alphabet (English 26 or Greek 24) → vowel or consonant filter → custom include list (intersection) → custom exclude list (subtraction) → case expansion. Choosing "both cases" doubles the remaining pool — A–Z then a–z — so mixed case is a genuine 52-entry pool with each form at 1/52, not an uppercase draw with a coin flip after it. Include and exclude lists are validated against the selected alphabet: a character that is not one of its letters is an error, never silently ignored. If the filters leave nothing, the tool says so. Every result reports the exact pool size the draw came from.
Draws without repeats
"No repeats" switches the engine to sampling without replacement, implemented as a partial Fisher–Yates shuffle driven by the same rejection sampler: each position swaps in a uniformly chosen letter from those not yet drawn. Drawing the whole pool this way yields a uniformly random permutation — every ordering equally likely. Asking for more unique letters than the pool holds is refused with an explanation of the actual limit, because the alternative — quietly repeating or quietly truncating — would be a lie about what you asked for.
Uniform only — no frequency weighting
Every letter in the active pool is exactly equally likely — the engine never weights draws by English text frequency or any other distribution.
That sentence is exported from the engine source itself and rendered here verbatim. A consequence worth stating: uniform randomness is streaky. The chance that a 6-letter sequence contains a repeated letter is about 46%, and five vowel draws can come up E every time at odds of exactly 1 in 3,125. Tools that never show streaks are not more random — they are less.
The Greek alphabet data
The Greek generator draws from a hand-checked table of the 24 modern Greek letters, alpha through omega, each with its uppercase form, lowercase form, and name. Lowercase sigma uses the medial form σ (the final form ς appears only at word ends, and the engine draws letters, not words — though typing ς in an include/exclude list is accepted as sigma). The automated tests assert the table's completeness: exactly 24 entries, the full canonical name sequence, distinct glyphs, and no Latin look-alike characters standing in for Greek ones. The alphabet table on the Greek page renders from this same data.
Worked examples can't drift
The example draws quoted in page copy are not typed in by hand: at build time, each page runs the real engine with a scripted byte source (for instance bytes 0, 7, 25 → A H Z), and the resulting letters are printed into the prose. If the engine's mapping ever changed, the copy would change with it — or the build would fail — so the documentation cannot silently disagree with the tool.
Privacy: nothing leaves the browser
The generators are static pages with client-side JavaScript. Your draws — the options you set and the letters you get — exist only in your browser tab: there is no server to send them to, no logging, and no storage; closing the page destroys the session. You can verify this yourself: open your browser's DevTools (F12) → Network tab and generate — you will see no request carrying your draw.
Tested, and fixed with tests
The engine's test suite drives the sampler with scripted byte sources to pin the exact byte-to-letter mapping (including the rejection path), exercises every pool composition (vowels ∩ exclusions, include lists, mixed case), covers the no-repeat exhaustion errors and count bounds, and locks the Greek alphabet data. If you believe a draw was outside the pool or a filter misbehaved, that is precisely the report we want — see the contact page. Confirmed issues are fixed in the engine and locked in with a new test so they cannot recur silently.