I'm working on a project that will mail out access codes. Yes, using physical snail mail. The recipient needs to be able read the code and accurately type it into a web form. The codes consist of seven characters including upper case A-Z, lower case a-z, and digits 0-9.

My question is how to communicate exact characters, keeping in mind that I might have a number 0 immediately next to the letter O. A code may also contain one, but not the other. I'm also concerned about i vs I vs l vs 1... and those are four different valid characters.

What fonts can I use that will clearly distinguish these? What are tests I can use to check the font? Are there other sets of similar character glyphs I might be missing? Is there anything else that I can/should be doing to make sure these are readable in an accurate way?

  • What is the feasibility of eliminating uppercase O from the code? Are your customers likely to give up after hitting a 0 instead of uppercase O?
    – ckpepper02
    Commented Jun 13, 2013 at 3:10

4 Answers 4


Search for programming fonts.

Character differentiation can be crucial when programming; these are fonts that are designed specifically with this sort of thing in mind.

Consolas is a very popular choice. Here's what those characters look like:


Here's a huge thread on programming fonts over at Stack Overflow: Recommended Fonts for Programming?

I don't want to change your criteria, but have you considered only distributing key codes that omit ambiguous characters? This is not an uncommon practice. For example, in the US all vehicles are required to have a VIN. As a measure of error prevention, they follow this rule:

does not include the letters I (i), O (o), or Q (q) (to avoid confusion with numerals 1 and 0)[1]

When the user inputs they key code, you could check for any of the invalid characters and have some sort of pop-up with a message like "Oops! You entered an I. Are you sure that's not a 1?"

  • It is very tempting (and would be fairly simple) to remove all six of those character glyphs from my alphabet, even if it does cut my key space in half (and thus reduce the security by an equivalent amount). And looking at the sample, I think I can just remove the upper case O. Everything else there is completely unmistakable. Commented Jun 13, 2013 at 2:45
  • Hmm... quick test says I also need to remove lower-case L. Commented Jun 13, 2013 at 2:50
  • I'll run some numbers tomorrow, and I'll accept this then if an alphabet size of 60 (no O or l) still meets my goals --- I want the rarity of a real match (in terms of avg # of guess required to get a hit) to be better than 1 in 1 billion, based on the key size and expected population size Commented Jun 13, 2013 at 2:53
  • Got impatient: the rarity comes to a little over 1 in 933 million. I think that will have to do, though, and even worse I'll lose another character: I'm leaning towards actually using Courier (for guaranteed availability) and dropping the upper O, lower L, and numeral 0. Commented Jun 13, 2013 at 3:07
  • @JoelCoehoorn I see what you mean about l, definitely very similar to 1 (I updated my post to include the glyph, not sure why I didn't in the first place). Good luck with it!
    – JohnB
    Commented Jun 13, 2013 at 3:08

Can't go wrong with Andale Mono.

Andale Mono

enter image description here

Changed my answer from Courier to Andale Mono

  • lower-L still looks like a one. numeral 0 and upper O could still confuse. Commented Jun 13, 2013 at 2:48
  • @JoelCoehoorn I can see your point on the O & 0
    – ckpepper02
    Commented Jun 13, 2013 at 2:53
  • @JoelCoehoorn Changed my answer to Andale Mono. O and 0 are distinguished, as well as the 1 and lowercase l.
    – ckpepper02
    Commented Jun 13, 2013 at 2:56
  • Would still need to drop the upper case O, but now it's one character better than consolas. I'm inclined to still drop the lower case L, too, because it's just ugly. I could see people going, "What in the world is that?". Also, Consolas is already installed on the machine where this will run, where I'm pretty sure I'd have to setup Andale Mono special. Commented Jun 13, 2013 at 3:01
  • Actually, I think I will go with Courier, in case we ever get to e-mail these. I know that will be available on any target system. Key space now down to 59 :( Commented Jun 13, 2013 at 3:05

OCR-B was designed for a similar purpose. All characters are easy to distinguish both by the human eye and for optical character recognition.

OCR-B replaced a previous font called OCR-A which exaggerated even more the differences between similar letters, at the expense of making it less pleasant for humans to read. You might have seen these on bank documents, cheques, pay slips etc:

Think about base-32 encoding

But you should also think of it in another way - why not encode your access code using Base 32 (crockford version) encoding? This is an encoding which excludes the letters I, L, and O to avoid confusion with numbers, and also excludes the letter U to prevent accidental obscenity in English. Then you can use just about any font.

  • Even in OCR-B, the letter O and digit 0 could be confused if you don't know the font and don't have both available to compare. Commented Jun 17, 2013 at 7:57
  • Indeed. I'm surprised they didn't use a dotted or slashed 0. Commented Jun 18, 2013 at 0:37
  • An interesting feature of uppercase or numeric OCR-A, which OCR-B lacks, is that every character includes unique features in both inked and non-inked areas. Errant marks or voids could render an OCR-A character unreadable, but only a combination of errant marks and voids could turn one uppercase or numeric OCR-A character into another (though I do find it curious that the difference between the top of the "B" and "P" is pretty slight).
    – supercat
    Commented Oct 28, 2014 at 21:09

A simple test is to go to MyFonts.com and type in a string for the sample text of all the similar characters and start looking.

For zeros, look for a font with a slashed-zero. The I/l/1 issue is a bit trickier, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.