Random Letter Generator

Draw truly random letters right here in your browser. Every option of the site’s focused tools in one place: count, English or Greek alphabet, upper/lower/mixed case, vowel and consonant filters, custom pools, and no-repeat draws — all cryptographically uniform, nothing transmitted.

Generate random letters

Pick your options and generate. Every letter in the pool is exactly equally likely.

Press Generate to draw letters.

What "cryptographically uniform" means here

The generator never invents randomness in JavaScript. It asks your browser’s Web Crypto API (crypto.getRandomValues) for raw random bytes — the same operating-system-backed source browsers use for encryption keys and secure tokens — and maps each byte onto the letter pool by rejection sampling. A byte holds 256 equally likely values; the full English pool holds 26. The engine keeps only the minimal bits that cover the pool — 5 bits for 26 letters, values 0 to 31 — and if the kept value lands at or beyond the pool size, it is thrown away and a fresh byte is drawn. Nothing wraps around, so no letter is ever more likely than another.

The mapping is literal. A kept value of 0 is the first letter of the pool, 25 is the last, and everything between counts along the alphabet. Scripted bytes 0, 7, 25 therefore produce A H Z. That example is not typed into this page: it is computed at build time by running the same tested engine the tool above uses, with a scripted byte source standing in for crypto.getRandomValues so the result is reproducible. Live draws use real random bytes and are not reproducible — that is the point of them.

Two more scripted bytes show the other half of the rule. Byte 200 is far above 31, but masking keeps only its low 5 bits, which leaves 8, and value 8 is I. Byte 29 survives the mask unchanged, but 29 is at or beyond 26, so it is rejected outright rather than wrapped onto a letter. Feeding the engine the bytes 200, 29, 2 in that order yields I C: 3 bytes consumed for 2 letters, with the middle byte discarded. The 5-bit mask has 32 possible values and the pool uses 26 of them, so 6 values — 26 through 31 — are always rejected.

Step-by-step guide: How a random letter is drawn walks a single draw from byte to letter, including a rejected byte, and sets out what "cryptographically uniform" does and does not promise. More walkthroughs are on the guides index.

Why the remainder shortcut is biased, and what rejection costs

The tempting shortcut — divide the byte by the pool size and keep the remainder — is biased because 256 is not a multiple of 26. Dividing 256 by 26 leaves a remainder of 22, which means 22 of the 26 possible results occur 10 times among the 256 byte values while the other 4 occur only 9 times. Under that shortcut A–V would each be about 11.1% more likely than W–Z. Small, but real, and permanent: no amount of drawing averages it away.

Rejection removes the bias at the price of a few wasted bytes. With 5 bits covering 26 letters, a kept value is accepted 26 times out of 32, an acceptance rate of 81.25%, so the engine consumes on average 1.23 bytes per letter. The minimal-bits rule guarantees that the pool always fills more than half of the kept range, which is why rejection never wastes more than half the draws and the average stays below two bytes per letter for every pool this tool can build. The cost is invisible in use and buys exactness. The uniformity claim rests on this construction, not on statistical testing of the output after the fact: the tool does not run a test on each batch and report a score, because none is needed when every byte is handled the same way.

Pools, filters, and cases compose

Every option on this page changes the pool, never the sampler. The pool is built in a fixed order: alphabet (English 26 or Greek 24) → vowel or consonant filter → include list (intersection) → exclude list (subtraction) → case expansion. The result box always reports the exact pool size the draw came from, so "equally likely" always has a number attached: 1 in whatever the box says.

The filter alone cuts the English alphabet to 5 vowels or 21 consonants. The exclude list then subtracts from whatever survived: consonants with the placeholder Q, X, Z removed is a pool of 18 — B C D F G H J K L M N P R S T V W Y — and scripted bytes 0, 17, 5 draw B Y H from it. A pool of 18 still needs 5 bits, so values 18 through 31 are rejected and acceptance drops to 56.25% — still above half, as the minimal-bits rule guarantees.

The include list works the other way, keeping only the letters you type. Typing the placeholder ABCDEF gives a 6-letter pool, which needs only 3 bits (values 0 to 7). Scripted bytes 7, 3, 5 produce D F: the first byte masks to 7, which is at or beyond 6 and is rejected; the next two map to letters. Include and exclude compose with the filter — vowels with E excluded leaves A I O U, a pool of 4 — and every character you type is validated against the selected alphabet before anything is drawn.

Case expansion comes last and applies to whatever remains. UPPERCASE and lowercase simply choose the form; "Both" appends the lowercase forms after the uppercase ones, so the full alphabet becomes a genuine 52-entry pool in which A and a are different entries, each at 1 in 52. The index arithmetic makes this visible: byte 0 is the first entry, and a byte equal to 26 — one past the last uppercase letter — is the first lowercase entry, so scripted bytes 0 and 26 draw A a. The doubled pool needs 6 bits, rejects 12 values, and accepts 81.25% of kept values. The Greek alphabet substitutes its own table of 24 letters, each with a name — byte 0 draws Α (Alpha) — and its pool rejects 8 of 32 kept values; the Greek page renders the whole table.

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. The pool is copied into a deck; for each position the engine draws a uniform index over the letters not yet taken and swaps that letter into place. A scripted source that returns byte 0 forever makes the mechanism visible: with repeats allowed it would draw the same letter every time, but without repeats it draws A B C, because each chosen letter leaves the deck and the "first remaining letter" moves along. Drawing the whole pool this way — all 26 letters, or all 52 in mixed case — yields a uniformly random permutation, every ordering equally likely. The limit is the pool itself: asking for 27 unique letters from 26 is refused with the engine’s own message, quoted below, rather than quietly repeating or truncating.

What the tool refuses, and how it tells you

Nothing is silently corrected. Each refusal below is real: it was produced at build time by passing the engine a deliberately bad request and printing the message it returned, and the tool above shows the same message in its result box (count errors are also marked on the count field).

  • Asking for 27 letters without repeats from the full alphabet: Cannot draw 27 letters without repeats from a pool of only 26 — allow repeats, lower the count, or widen the pool.
  • Asking for 101 letters, one past the limit: How many: enter a whole number from 1 to 100.
  • Typing a digit into the include list: The include list contains “1”, which is not a letter of the selected alphabet.
  • Excluding every vowel from the vowel pool: The selected filters leave no letters to draw from — relax the filters.

The count must be a whole number from 1 to 100, every character in an include or exclude list must be a letter of the selected alphabet, and a pool must contain at least one letter. A pool of exactly one letter is legal, though: include only Q and the tool draws Q Q Q every time and reports a pool size of 1, which is the correct answer, not a fault.

Uniform only — no weighting, and nothing more

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 and rendered here verbatim. It is the whole of the distribution: the engine has no setting for weighting draws by English text or anything else, and no page on this site will imply one. It is also where the tool stops. It draws letters from a stated pool with each entry at exactly 1 in the pool size, reports that pool size, and claims nothing beyond the construction described on this page; the methodology page states the same limits. What you can check for yourself is that nothing leaves your browser: open the Network tab in your browser’s developer tools, generate, and no request carries your draw.

Reading the result: streaks are normal

Uniform randomness is streaky, and a tool that hid the streaks would be less random, not more. The figures here are pool arithmetic, computed from the pool size. Whatever letter you just drew, the next independent draw repeats it with probability 1 in 26. The chance that a 6-letter batch with repeats allowed contains at least one repeated letter is about 46%, so doubles are the expected case, not a sign that something is wrong. A batch of 3 draws all showing the same letter happens once in 676 batches — rare, but not evidence of a fault. In the other direction, draw 26 letters with repeats allowed and the chance that any particular letter — Q, say — never appears at all is about 36%, because the expected count of each letter is one and the spread around that average is wide.

Two misreadings are worth naming. First, "Both (doubles the pool)" is not a coin flip after a draw. It is a 52-entry pool, and the reported pool size says so; the difference matters most with "no repeats", where A and a can both appear in one batch. Second, "no repeats" does not make draws more random — it makes them dependent. Each letter removed changes the pool for the next position, which is exactly what you asked for, and exactly why 52 letters is the most a mixed-case batch can hold.

Where the one-of-everything generator fits

This page carries every option so that the pool can be shaped to a rule you already have: a letter-a-round game where already-used letters go into the exclude list, a pick between players by distinct initials with "no repeats" on, a custom include list of exactly the letters you need, or placeholder strings for test data that carry no accidental meaning. When the question is simpler, the focused tools answer it with no setup — vowels, consonants, multi-letter sequences, mixed case, and the Greek alphabet with letter names — and the guide to how a letter is drawn explains the shared engine behind all of them.

Frequently asked questions

Is every letter really equally likely?

Yes, by construction. The generator asks your browser’s cryptographic random source for raw bytes, keeps only the minimal bits needed to cover the pool (5 bits for the 26-letter alphabet), and discards any value that falls outside it before redrawing. That rejection-sampling step is what removes the small bias that the common "random number modulo 26" shortcut introduces. Every letter in the active pool has exactly the same probability — 1 in 26 across the full English alphabet.

Are letters weighted by how common they are in English?

No, and the site will never quietly pretend otherwise. The engine is uniform-only: E and Z are drawn with exactly the same probability, 1 in 26, and so is every other letter in the active pool. Nothing in the engine knows anything about English text, and no option on this page introduces weighting.

Can I stop letters from repeating?

Yes — switch on "no repeats" and the generator draws without replacement, so every letter in the batch is distinct. If you ask for more letters than the pool holds (say 27 unique letters from the 26-letter alphabet), the tool refuses with the actual limit instead of silently repeating: “Cannot draw 27 letters without repeats from a pool of only 26 — allow repeats, lower the count, or widen the pool.”

How do the custom include and exclude lists work?

The include list restricts the pool to exactly the letters you type; the exclude list removes letters from whatever pool is active. They compose with the vowel/consonant filter — vowels with E excluded leaves A I O U, a 4-letter pool. Spaces and commas between letters are ignored, letter case does not matter, and any character outside the selected alphabet is rejected with an error rather than ignored.

Should I use the include list or the exclude list?

Whichever describes your pool more briefly — the engine sees only the pool that results, never which list produced it. Two settings that leave the same letters are the same pool: consonants with Q, X, Z excluded is the 18-letter pool B C D F G H J K L M N P R S T V W Y, and typing those 18 letters into the include list with the filter on "All letters" builds the identical pool, so the same scripted bytes 0, 17, 5 draw B Y H either way and the result reports the same 18. If both lists are filled, inclusion is applied first and exclusion second, so a letter that appears in both is removed.

What changes when I switch the alphabet to Greek?

Only the table the pool is built from. The engine swaps the 26 English letters for its own 24-letter Greek table, alpha through omega, and every other option then applies to that table: the vowel/consonant filter, the include and exclude lists, and case expansion, which gives a pool of 48 with "Both". Lists are validated against the alphabet you selected, so a Latin letter typed into the include list while Greek is selected is refused rather than mapped onto a look-alike: “The include list contains “A”, which is not a letter of the selected alphabet.” The sampler itself is unchanged — 5 bits cover the pool and 8 of 32 kept values are rejected — and the result reports a pool size of 24.

What happens if I leave the count blank, or type a number outside the range?

A blank count draws a single letter — the form’s default, shown as the field’s placeholder. A count that is not a whole number (a decimal, a minus sign, a word) is caught before the engine is called: the count field is marked and the result box asks you to fix it. A whole number outside 1 to 100 reaches the engine, which refuses it before any byte is drawn — “How many: enter a whole number from 1 to 100.” — and the tool shows that message on the count field and in the result box. Nothing is clamped to the nearest legal value.

Is anything I generate sent anywhere?

No. The draw runs as JavaScript in your browser using your device’s own cryptographic random source. Nothing is transmitted, logged, or stored; closing the page discards everything.

Uniform means uniform: draws are never weighted by English letter frequency or anything else, and streaks are a normal property of real randomness. Letters are drawn locally in your browser and never transmitted. How the engine works and is tested is on the methodology page.