Free preview

Why Base 58

In one line: this is a design decision made entirely for humans, and the six characters removed fall into two categories for two different reasons.

The argument

Our sequencer generates a 64-bit ID in base-10, which can be converted to a base-64 short URL. Base-64 is the most common encoding for alphanumeric strings. However:

  • The generated short URL might be hard to read due to look-alike characters. Characters like O (capital o) and 0 (zero), I (capital i) and l (lowercase L) can be confused.
  • Characters like + and / should be avoided because of other system-dependent encodings.

So, we slash out the six characters and use base-58.

Base 64 = A-Z (26) + a-z (26) + 0-9 (10) + '+' + '/'  = 64
Remove:   0   O   I   l   +   /                       = -6
                                                        ----
Base 58                                                 = 58

Two different problems, two different fixes — and only one is about humans

The six removals look like one decision. They are two.

RemovedWhyWhose problem
0, O, I, lVisually ambiguous in most fontsThe human reading or typing it
+, /Not URL-safe — they have meaning in URLsThe machine parsing it

The first four are a transcription problem. Someone reads a short URL off a poster, a business card, or a phone screen and types it. rvV0lIO is a nightmare; is that a zero or a capital O? Is that a lowercase L or a capital I?

The last two are an encoding problem, and it is serious rather than cosmetic. In a URL, / is a path separator — a short code containing it would split the path. And + in a query string is conventionally decoded as a space. Neither is a matter of taste; both would break.

That is why the standard remedy for + and /base64url, which substitutes - and _ — solves only half the problem. It fixes the machine's complaint and leaves the human's.

Base 58 is base64url plus a legibility pass, and knowing that it addresses two distinct failure modes is what makes the choice defensible rather than arbitrary.

The character set

RangeCharacters
Digits1 2 3 4 5 6 7 8 9 — no 0
UppercaseA B C D E F G H J K L M N P Q R S T U V W X Y Z — no I, no O
Lowercasea b c d e f g h i j k m n o p q r s t u v w x y z — no l

Notice which member of each confusable pair survives

The choices are not arbitrary, and the pattern is consistent:

0 vs O  ->  keep 'O'    (drop the digit)
1 vs l vs I  ->  keep '1' and 'i'    (drop 'l' and 'I')

So from 0/O the letter survives; from 1/l/I the digit and lowercase i survive.

Why this particular split? Because it removes ambiguity in both directions. If you kept both 0 and O, a reader seeing a round glyph could not tell which was meant. Removing one makes the glyph unambiguous — whatever it looks like, there is only one thing it can be.

The same set is used by Bitcoin addresses, which face an identical problem: humans transcribing long identifiers where a single error is unrecoverable. That is a useful reference point in an interview — it shows the choice is a known convention rather than something invented for this design.

When two symbols are visually confusable, removing one is better than distinguishing them, because you cannot control the font your users read it in.

What base 58 costs, and it is almost nothing

Dropping from 64 to 58 symbols means each character carries slightly less information:

Base 64:  log2(64) = 6.00 bits per character
Base 58:  log2(58) = 5.86 bits per character
                     -------------------------
Loss:                2.4% per character

Over a 64-bit ID:

Base 64:  64 / 6.00 = 10.7  -> 11 characters
Base 58:  64 / 5.86 = 10.9  -> 11 characters

Identical length. The 2.4% loss is not enough to add a character.

That is a very good trade: measurably better legibility and URL safety, at zero cost in URL length. Worth stating explicitly in an interview, because the instinctive objection to base 58 is "you're wasting bits" — and here the waste rounds away entirely.

The general form: when a change costs less than one unit of the thing you care about, it is free. Six symbols out of sixty-four sounds like a lot; it is under a tenth of a character.

Alternatives worth knowing

Base 58 is a good answer and not the only one.

Base 32 (RFC 4648, or Crockford's variant) uses 32 symbols, excludes I, L, O, U — the last to avoid accidental profanity — and is case-insensitive, which is a genuine advantage for URLs read aloud or typed on mobile keyboards. The cost is length: 5 bits per character means a 64-bit ID needs 13 characters rather than 11.

Base 62 keeps all alphanumerics and drops only + and /. URL-safe, and it leaves the look-alike problem entirely to the user.

Base64url substitutes - and _, solving only the machine's problem.

SymbolsBits/char64-bit IDCase-insensitiveLook-alikes removed
Base 32325.0013 charsYesYes
Base 58585.8611 charsNoYes
Base 62625.9511 charsNoNo
Base64url646.0011 charsNoNo

Base 58 sits at a sensible point: the shortest option that also fixes legibility. Base 32's case-insensitivity is genuinely tempting for a service whose URLs get read aloud, and two extra characters is a real cost — which is exactly the kind of trade worth raising rather than treating as settled.

The alphabet is a human-factors decision, not a mathematical one. Losing six characters costs a fraction of a character in length and removes an entire class of transcription error.

Key takeaway

The six removed characters solve two different problems: 0, O, I, l are a human transcription problem, while + and / are a machine parsing problem — / is a path separator and + decodes as a space, so both would genuinely break. Base 58 is base64url plus a legibility pass. From each confusable pair exactly one survives, because you cannot control the font your users read. And the cost is effectively zero: 5.86 bits per character versus 6.00 still gives 11 characters for a 64-bit ID, so the 2.4% loss rounds away entirely. Base 32 is the interesting alternative — case-insensitive, at the price of two extra characters.

Next: the conversions, worked in both directions.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue