Developer · 4 min read ·
Base64 explained: what it’s for, and why it isn’t encryption
Base64 shows up in emails, data URIs, API headers and JWTs. Here is how it works, why it makes data a third bigger, and why it never hides anything.

Base64 is everywhere in software: email attachments, images embedded in CSS, the Authorization header of HTTP Basic auth and the parts of a JWT. It has one job: to write any data, including binary bytes, using only safe text characters.
How it works
Base64 takes the data three bytes (24 bits) at a time and splits them into four groups of 6 bits. Each group is a number from 0 to 63 that maps to one of 64 characters: A-Z, a-z, 0-9, + and /. When the input doesn’t divide into groups of three, = signs pad the end.
Text M a n
Bytes 01001101 01100001 01101110
6 bits 010011 010110 000101 101110
Base64 T W F u → TWFu
Why it exists
Many older systems, email above all, were built for text and could damage arbitrary bytes. Base64 turns anything into plain characters that pass through those channels unchanged. The cost is size: every 3 bytes become 4 characters, so encoded data is about 33% larger.
It is not encryption
There is no key. Anyone can decode Base64 instantly, so it hides nothing. A password in a Basic auth header (dXNlcjpwYXNz is simply user:pass) is as exposed as plain text. Protect secrets with HTTPS and real encryption, and never treat Base64 as a security measure.
Variants you will meet
Base64url replaces + and / with - and _ and usually drops the padding, so the result is safe in URLs and file names; JWTs use it. Data URIs put encoded data inline, like data:image/png;base64,iVBOR…, which saves a request for tiny images but makes larger ones heavier.
Size in numbers
The encoded length is 4 × ceil(n / 3) characters for n bytes, so the overhead is about 33%, plus line breaks if the encoder adds them.
100 KB image → about 133 KB of Base64
1 MB attachment → about 1.33 MB (plus line breaks in email)
Why decoding fails
- Missing padding: some systems drop the trailing = signs, and strict decoders then refuse the input. Add = until the length is a multiple of 4.
- The wrong alphabet: Base64url uses - and _ instead of + and /. Decode it with a Base64url decoder, or swap the characters back first.
- Line breaks and spaces: email (MIME) wraps Base64 at 76 characters per line. Most decoders ignore the breaks, but some don’t.
- Text in the wrong encoding: decoding gives you bytes. If they were UTF-8 text but are read as Latin-1, accented letters and Hebrew turn into gibberish.
The JavaScript btoa trap
The browser’s built-in btoa() only accepts characters from Latin-1 and throws an error for Hebrew, Chinese or emoji. Encode the text to UTF-8 bytes first, for example with TextEncoder, and then to Base64.
When to use it, and when not
Base64 is the right tool when binary data has to travel through a channel built for text: JSON and XML payloads, email, data URIs and HTTP headers. It is the wrong tool for hiding data, for shrinking it (it always grows) and for storing large files in a database, where a binary column or object storage is smaller and faster. If the receiving side accepts raw bytes, send raw bytes.
Try it
The 4Dev Base64 Encoder converts text to Base64 as you type. It uses UTF-8, so accented letters, Hebrew, emoji and any other non-English text encode correctly. To go the other way, use the Base64 Decoder.