Dark monitor filled with dense rows of glowing encoded characters
Dev Tools

The Base64 Alphabet and Padding Explained (=, +, /)

The 64 Characters That Make Up Base64

Base64 has a fixed, standard alphabet โ€” exactly 64 symbols, plus one extra character used only for padding. Every valid Base64 string is built entirely from this set. If a character outside it appears in the middle of your data, the string is not valid Base64 and a strict decoder will reject it. Understanding which characters are legal, which are not, and why the padding (=) shows up is the fastest way to debug a Base64 string that "looks wrong."

The alphabet is defined in RFC 4648, the standard that formalizes Base16, Base32, and Base64. For the standard encoding (RFC 4648 ยง4), the 64 characters map to index values 0 through 63 like this:

  • Indices 0โ€“25: the uppercase letters A to Z
  • Indices 26โ€“51: the lowercase letters a to z
  • Indices 52โ€“61: the digits 0 to 9
  • Index 62: the plus sign +
  • Index 63: the forward slash /

That is the whole alphabet: 26 + 26 + 10 + 2 = 64. The two non-alphanumeric symbols, + and /, are the ones that surprise people โ€” they are completely normal Base64 characters, not corruption. The padding character = is separate and is not part of the 64-value alphabet; it appears only at the very end of a string, never in the middle.

Which Characters Are NOT Valid Base64

This is the question behind "which characters are not Base64" and "Base64 illegal characters." The answer is simple: anything outside the set Aโ€“Z, aโ€“z, 0โ€“9, +, and / (with = allowed only as trailing padding). That means every one of these is invalid inside a Base64 payload:

  • Spaces and tabs โ€” a stray space is the single most common reason a decode fails.
  • Line breaks (\n, \r) โ€” legal only in the MIME variant, which wraps lines every 76 characters; a strict decoder in "no whitespace" mode rejects them.
  • Percent signs (%), which usually mean the string was URL-encoded and needs decoding first.
  • Punctuation such as ., ,, :, ;, @, #, *, quotes, and brackets.
  • The URL-safe substitutes - and _ โ€” legal in the URL-safe alphabet, but not in the standard one, and mixing the two breaks decoding.
  • Any non-ASCII or accented character (รฉ, รฑ, emoji, "smart quotes" pasted from a word processor).

This directly explains why a Base64 block can look illegible or fail to decode. A valid Base64 string is uniform: nothing but the 64 alphabet characters and, at most, one or two trailing =. When you see something that will not decode, it almost always contains one of the invaders above โ€” a hidden newline copied from a terminal, a leading space, a % from URL encoding, or curly quotes from a PDF. The data itself is not "illegible"; it is contaminated by characters that are not in the alphabet. Strip the foreign characters (or decode the outer layer first) and the block becomes valid again.

How Encoding Produces Those Characters

To understand the alphabet you have to see where the index values come from. As MDN's Base64 glossary summarizes, Base64 works on 3 bytes at a time. Three bytes are 24 bits, and 24 divides evenly into four groups of 6 bits. Each 6-bit group is a number from 0 to 63 (because 26 = 64), and each of those numbers selects one character from the alphabet above. So every 3 input bytes become exactly 4 output characters โ€” that 4-for-3 ratio is also why Base64 output is about 33% larger than the input.

The reason the alphabet is exactly 64 symbols is this 6-bit boundary. Six bits can express 64 distinct values and no more, so the encoding needs precisely 64 printable characters to have a one-to-one mapping. Fewer would not cover all values; more would waste the clean bit alignment.

A Worked Example: "Man" Becomes "TWFu"

Take the three ASCII characters Man. Their byte values are 77, 97, 110, which in binary are:

  • M = 77 = 01001101
  • a = 97 = 01100001
  • n = 110 = 01101110

Concatenated, that is the 24-bit string 010011010110000101101110. Split into four 6-bit groups: 010011, 010110, 000101, 101110 โ€” which are the index values 19, 22, 5, and 46. Look those up in the alphabet: 19 โ†’ T, 22 โ†’ W, 5 โ†’ F, 46 โ†’ u. The result is TWFu. Because the input was exactly three bytes, the output is a clean four characters with no padding.

Why Padding Exists: The "=" Character

Real data is rarely a perfect multiple of three bytes. When the final group has only one or two bytes instead of three, there are not enough bits to fill four output characters โ€” so Base64 pads the output with = to keep the length a multiple of four. The rule is precise:

  • Input length โ‰ก 0 (mod 3): no padding. Four real characters, e.g. TWFu.
  • Input length โ‰ก 2 (mod 3) (one byte short): one =. Two leftover bytes = 16 bits = three 6-bit groups (with two zero bits added), so three real characters + one =.
  • Input length โ‰ก 1 (mod 3) (two bytes short): two ==. One leftover byte = 8 bits = two 6-bit groups (with four zero bits added), so two real characters + ==.

Example: encode Ma (just two bytes: 77, 97). The 16 bits 0100110101100001 become three 6-bit groups 010011, 010110, 0001+00 padding = 19, 22, 4 โ†’ T, W, E, then one = to round out the quartet. The result is TWE=. Encode a single byte M (77) and you get TQ== โ€” two real characters and two padding signs.

The = tells the decoder how many bytes the final group really represents so it can discard the extra zero bits. Some systems (notably URL-safe Base64 in JWTs) drop the padding entirely because the length is recoverable, but in standard Base64 the padding makes the string self-describing and its length always divisible by four. If you ever see a Base64 string whose length is not a multiple of four and it has no padding, that is a strong hint it was truncated or had padding stripped.

Metal letterpress type blocks arranged in a tight grid in a wooden tray

Why a Base64 String Can Start With "/"

People often ask whether it is normal for a Base64 string to start with a slash (/) โ€” or with +. It is completely normal. The slash is index 63, a first-class member of the standard alphabet, and the very first six bits of your data are just as free to be 111111 (63) as any other value. Any byte sequence whose leading six bits happen to be all ones produces a / at the front. There is nothing special, broken, or suspicious about it.

The reason it feels alarming is that a leading / looks like a file path, and a leading + looks like it belongs in arithmetic โ€” but inside a Base64 string they are ordinary characters. The one situation where a leading / or + causes trouble is when the string is placed into a URL without being URL-safe encoded: there, / reads as a path separator and + reads as a space. That is exactly the problem the URL-safe variant solves, not a sign that your encoding is wrong. If your Base64 lives inside a URL, use the URL-safe alphabet described next; everywhere else, a leading / is expected. You can confirm any of this with our browser-based Base64 encoder/decoder.

The URL-Safe Alphabet: "-" and "_"

RFC 4648 ยง5 defines a second alphabet for exactly the /-and-+ problem. It is identical to the standard one except that index 62 becomes - (hyphen) instead of +, and index 63 becomes _ (underscore) instead of /. Those two substitutes are safe to drop straight into URLs and filenames without percent-encoding, which is why JSON Web Tokens, many APIs, and cache keys use it. Padding is usually omitted in the URL-safe form as well.

The critical point is that the two alphabets are not interchangeable inside a single string: a decoder configured for standard Base64 will reject - and _, and a URL-safe decoder will reject + and /. If you are debugging a string that contains hyphens or underscores, you are almost certainly looking at URL-safe Base64. We cover the differences and conversion rules in depth in Base64 URL-safe vs standard encoding, and the broader mechanics in Understanding Base64 encoding.

"Base44" vs Base64: Clearing Up the Confusion

A recurring search is the "difference between Base64 and Base44." The short answer: Base64 is the standard binary-to-text encoding, and "Base44" is not a recognized standard for that purpose. There is no equivalent of RFC 4648 defining a general-purpose Base44 binary-to-text scheme, so if you were told to produce or consume "Base44" data, it is worth confirming what was actually meant.

Usually one of a few things is going on. The term may be a typo or mishearing of Base64. It may refer to a specific application's custom character set (some systems define their own reduced alphabets for short IDs or human-friendly codes, and give them ad-hoc names), in which case only that application's documentation defines it. Or it may be confused with the well-known relatives in the same RFC โ€” Base32 and Base16 โ€” which are standardized. For interoperable data exchange, reach for Base64 (or its URL-safe variant); it is the encoding libraries, browsers, and protocols agree on. We are deliberately not making claims about the internals of any particular "Base44" implementation, because no single standard defines one.

A Quick Debugging Checklist

When a Base64 string will not decode, walk through the alphabet rules in order:

  • Scan for foreign characters. Anything outside Aโ€“Z aโ€“z 0โ€“9 + / (plus trailing =) is the culprit โ€” usually whitespace, a newline, or a %.
  • Check the length. Standard Base64 is always a multiple of four once padding is included. A length that is off by one, two, or three suggests stripped padding or truncation.
  • Look for - or _. If present, it is URL-safe Base64; decode it with a URL-safe decoder, not the standard one.
  • A leading / or + is fine โ€” unless the string is sitting unescaped inside a URL, in which case it needed the URL-safe alphabet.
  • Decode outer layers first. If you see %2F or %3D, the string was URL-encoded; percent-decode it before treating it as Base64.

Once you can look at a string and immediately tell whether every character belongs to the alphabet, Base64 stops being mysterious. The "illegible" blocks resolve into either valid data or clearly contaminated data, and the =, +, and / characters read as exactly what they are. Try any string in our free, browser-only Base64 encoder/decoder โ€” nothing is uploaded, and it will flag characters that fall outside the alphabet.

Sources

← Back to Blog