25 characters. Zero confusion.
An open standard for human-safe identifiers. Visually distinct in any typeface, at any size, for any reader — including those with dyslexia.
Every ambiguous character in an ID is a future support ticket. HardGuard25 removes the 11 letters that get misread, mis-dictated, and OCR'd wrong — and keeps all ten digits so versioning stays natural.
Why these 25 characters?
Standard alphanumerics give you 36 characters (0–9, A–Z). That creates real problems when a human reads, transcribes, or dictates a code out loud. HardGuard25 keeps all ten digits and fifteen carefully chosen letters, removing eleven sources of confusion. Design principle: when a letter and a digit compete for the same visual slot, the digit always wins.
Visually distinct
No confusable pairs — no more O vs 0, I vs 1, S vs 5, or B vs 8 in printed or dictated identifiers.
Dyslexia-aware
Mirror pairs (B/D, Q/P) and visually-similar shapes (E/3) are removed to reduce error rates for dyslexic readers.
OCR-friendly
Works reliably with OCR-A, Menlo, and other monospace typefaces on receipts, labels, and printed materials.
| Removed | Reason |
|---|---|
| O | Confusable with 0 (zero) |
| I | Confusable with 1 (one) and lowercase L |
| L | Confusable with 1 (one) and uppercase I |
| B | Confusable with 8; dyslexia mirror pair with D |
| S | Confusable with 5 |
| Z | Confusable with 2 |
| E | Confusable with 3 for dyslexic readers; digits take priority |
| Q | Confusable with O in some typefaces; dyslexia mirror pair with P |
| V | Confusable with U in many typefaces |
| T | Resembles a plus sign in some contexts |
| X | Collides with multiplication operator; varies by locale |
Entropy and length
Each HardGuard25 character carries log2(25) ≈ 4.64 bits of entropy. Pick a length for your risk profile:
| Length | Unique IDs | Sweet spot for |
|---|---|---|
| 4 | 390,625 | Small inventory, tickets |
| 6 | 244 million | Medium businesses |
| 8 | 152 billion | Large systems |
| 12 | 59.6 trillion | Internal tokens |
| 16 | 3.55 × 1022 | Cross-system identifiers |
| 20 | 2.11 × 1027 | Public tokens |
Install
Reference implementations are available in JavaScript, Python, and Go. Each includes generation, validation, normalization, and an optional Mod-25 check digit.
JavaScript
npm install @snapsynapse/hardguard25
import { generate, validate, normalize, checkDigit }
from '@snapsynapse/hardguard25';
generate(8); // "AC3H7PUW"
generate(8, { checkDigit: true }); // + check char
validate("AC3H-7PUW"); // true
normalize("ac3h-7puw"); // "AC3H7PUW"
Python
pip install hardguard25
from hardguard25 import (
generate, validate, normalize, check_digit,
)
generate(8) # "AC3H7PUW"
generate(8, check_digit=True) # + check char
validate("AC3H-7PUW") # True
normalize("ac3h-7puw") # "AC3H7PUW"
Go
import "github.com/snapsynapse/hardguard25/go"
id, _ := hardguard25.Generate(8)
id, _ = hardguard25.GenerateWithCheck(8)
ok := hardguard25.Validate("AC3H-7PUW")
s := hardguard25.Normalize("ac3h-7puw")
No library needed
# Alphabet 0123456789ACDFGHJKMNPRUWY # Regex ^[0-9ACDFGHJKMNPRUWY]+$ # Normalization: trim, strip separators, # uppercase, reject anything outside the set.
The alphabet is the standard. If you just need the character set, use it directly.
Try it live
The interactive generator produces real HardGuard25 codes in the browser — pick a length, quantity, grouping, case, and optional check digit.