Base64 padding and the equals sign
You paste a string into a Base64 encoder and the result sometimes ends in =, sometimes ==, and sometimes nothing at all. That trailing character is not noise and it is not optional in classic Base64. It is padding, and it exists to keep the output a clean multiple of four characters.
Why Base64 works in groups of three
Base64 turns binary into text by reading the input three bytes at a time. Three bytes is 24 bits, and 24 divides evenly into four groups of 6 bits. Each 6 bit group becomes one character from the 64 character alphabet. So every three input bytes produce exactly four output characters, with nothing left over.
The problem is that real input is rarely a multiple of three bytes. When the final group has only one or two bytes, there are not enough bits to fill four output characters. Padding fills the gap.
How the padding count maps to input length
The number of = characters at the end tells you the length of the input modulo three.
- Input length divisible by 3 → no padding.
- Input length leaves remainder 2 → one
=. - Input length leaves remainder 1 → two
==.
A short example makes the pattern concrete:
"Man" (3 bytes) -> "TWFu" (no padding)
"Ma" (2 bytes) -> "TWE=" (one pad)
"M" (1 byte) -> "TW==" (two pads)
With two leftover bytes you have 16 bits, enough for three characters plus two padding bits, so one slot is empty and gets one =. With one leftover byte you have 8 bits, enough for two characters, so two slots are empty and you get ==. The padding bits themselves are always zero, which is why a decoder can reconstruct the exact original byte count.
When padding is dropped
The = character is awkward in some contexts. It is reserved in URLs and query strings, and it can confuse parsers that split on it. The base64url variant, defined in RFC 4648, addresses this by replacing + and / with - and _, and it commonly omits the padding entirely.
This is why JSON Web Tokens look like three unpadded base64url chunks joined by dots. A decoder can still recover the data because the length of the string already implies how many bytes were encoded. If you ever feed an unpadded string into a strict decoder that demands padding, the fix is simply to append enough = characters to round the length up to a multiple of four.
You can watch all of this happen as you type in the Base64 Encode / Decode tool. It runs entirely in your browser, so the input never leaves your device, and it supports both the standard and URL safe variants. If you want the deeper treatment of the URL safe form, see URL safe Base64 and base64url, and remember that Base64 is not encryption.
The practical takeaway: padding is just bookkeeping about input length. One = means two leftover bytes, two means one leftover byte, and base64url usually drops the markers because the string length already carries the information.