Base64 encoding, explained
Some systems only handle text. Email bodies, JSON payloads, URLs, the CSS file behind a web page: none of them were built to carry raw binary. Base64 is the workaround. It takes any binary data and rewrites it using 64 plain-text characters, so the data can ride through a text-only channel and come out the other side unchanged.
That's the whole job. Base64 isn't compression, and it isn't encryption. It's a reversible way to spell binary in an alphabet that text systems won't mangle.
When you'd actually use it
You run into Base64 more often than you'd think, usually without noticing.
When an API only accepts JSON and you need to send a file, you Base64 the file and drop the string into a field. When you embed a small icon directly in a stylesheet instead of making the browser fetch a separate image, that data: URI is Base64. Email attachments have traveled this way for decades, because the mail protocols underneath only guarantee safe passage for text. The Authorization: Basic header your HTTP client sends is just username:password in Base64. And the header and payload of a JWT are base64url, a close cousin we'll get to below.
The pattern is always the same: binary needs to pass through something that only trusts text, so you spell it in Base64 first and decode it on the far side.
How it works
Base64 works in groups of three bytes.
Three bytes is 24 bits. Base64 slices those 24 bits into four groups of 6 bits each. Six bits can represent 64 values (2 to the 6th), and that's where the name comes from: every 6-bit group maps to one character in a 64-character alphabet. So every 3 bytes of input become exactly 4 characters of output.
The alphabet is fixed. A–Z cover values 0–25, a–z cover 26–51, 0–9 cover 52–61, and then + and / cover 62 and 63. All 64 are printable ASCII characters that survive text channels intact.
What if your data doesn't divide evenly into threes? Then Base64 pads. If one byte is left over, the encoder fills the gap and adds two = signs. If two bytes are left over, it adds one =. The padding keeps the output a clean multiple of four characters, which is what tells a decoder where the real data stops and the filler begins.
A worked example
Take the word Man. Three letters, three bytes, so it encodes in one clean group with no padding.
In ASCII, M is 77, a is 97, n is 110. As bits:
M a n
01001101 01100001 01101110
Glue those together and re-slice into 6-bit groups:
010011 010110 000101 101110
19 22 5 46
Now look each value up in the alphabet: 19 is T, 22 is W, 5 is F, 46 is u. So Man becomes TWFu.
Drop the last letter and encode just Ma, and you're left with two bytes. That doesn't fill a full group, so you get TWE= with a single padding character. Encode only M, and one byte gives you TQ==.
Try it in your browser
All three of these run on your device. Nothing you paste or upload is sent to a server, so you can encode credentials, internal config, or a private image without any of it leaving your tab.
- Base64 Encoder — encode text or files, with a URL-safe toggle and MIME line splitting.
- Base64 Decoder — decode a string or file back to its original bytes, with a live preview.
- Image to Base64 — turn an image into a
data:URI you can paste straight into CSS or HTML.
Common mistakes
Base64 is not encryption. This is the one that bites hardest. Anyone can decode Base64 in a second, so a token or password "hidden" in Base64 is sitting in plain sight. If you need secrecy, reach for real encryption or password hashing, not this.
It makes data bigger. Four characters out for every three bytes in works out to about 33% larger, before you even count padding or line breaks. Base64 is the opposite of compression. If you're encoding to save space, you're going the wrong way.
Standard Base64 breaks in URLs. The + and / characters mean other things inside a URL, so a normal Base64 string can corrupt when it lands in a query parameter or path. That's why the URL-safe variant exists: it swaps + for - and / for _, and often drops the = padding. JWTs use this variant for exactly that reason.
Padding strictness varies. Some decoders demand the = padding and reject a string without it; others don't care. If a decode fails on a string that otherwise looks fine, a missing or extra = is a good first suspect.
FAQ
No. It offers no secrecy at all. It's an encoding, not a cipher, and reversing it takes no key and no effort. Treat any Base64 string as readable by anyone who has it.
Because the format trades size for portability. Every 3 bytes become 4 characters, so expect roughly a third more, plus a little for padding. That overhead is the price of passing binary through a text-only channel.
Same idea, two characters different. base64url replaces + with - and / with _ so the result is safe to drop into a URL, and it usually omits the = padding. You'll see it in JWTs and in plenty of web APIs.
That's padding. It shows up when your input length isn't a multiple of three bytes. One = means two leftover bytes; two = means one leftover byte. It's normal, and the decoder either needs it or needs to know it was dropped.
Yes. Encode the image bytes, wrap them in a data: URI, and you can embed the picture directly in CSS or HTML with no separate file request. Our Image to Base64 tool builds the full URI for you. It's handy for small images; for large ones, the 33% size bump usually isn't worth it.
Related guides
- JWT (JSON Web Tokens) explained — where base64url shows up in the wild, and why a decoded JWT isn't a verified one.
- URL encoding and parsing — the other everyday encoding, solving a different text-safety problem.
- Hashing and password storage — what to reach for when you actually need secrecy instead of text-safe transport.