Developers

What Is Base64 Encoding? How It Works, With Examples

8 min read

Base64 encoding is a way to represent any data, text or binary, using only 64 printable ASCII characters, so it survives systems that were only ever built to handle plain text safely. It is not encryption and it is not compression. It is a reversible format conversion, and anyone can undo it in one step.

What Base64 encoding actually does

Base64 takes raw bytes and re-expresses them using a fixed alphabet of 64 symbols: A-Z, a-z, 0-9, plus + and /. Every 3 bytes of input become exactly 4 Base64 characters, so the encoded output ends up about 33% larger than what went in.

That last point trips people up constantly, so it is worth stating plainly: Base64 makes data bigger, not smaller, and it uses no key of any kind. If you “encode” a password in Base64 and store it like that, you have not protected it. Anyone with five seconds and a text editor can decode it back to plain text. Base64 solves a transport problem (can this byte sequence survive being pasted into a text field, a URL, or a JSON string?), not a security problem. If you need secrecy, that is what hashing and encryption are for, and neither has anything to do with Base64.

How it works: encoding “Man” bit by bit

The name gives it away: Base64 is a base conversion. Regular bytes are base 256 (8 bits each, 256 possible values). Base64 regroups those same bits into 6-bit chunks, and each 6-bit chunk (64 possible values, 0 to 63) maps to one character in the alphabet.

Take the text “Man”. Its three ASCII byte values are M=77, a=97, n=110. Written in binary, that’s:

CharacterByte valueBinary (8 bits)
M7701001101
a9701100001
n11001101110

Concatenate all 24 bits in order: 010011010110000101101110. Now split that same string of bits into four groups of 6, ignoring the original byte boundaries entirely:

010011 | 010110 | 000101 | 101110

Each 6-bit group is just a number from 0 to 63. Convert them to decimal and look each one up in the Base64 alphabet:

6-bit groupDecimal valueBase64 character
01001119T
01011022W
0001015F
10111046u

Read the characters in order and “Man” becomes “TWFu”. Nothing about that is magic: 3 bytes (24 bits) split cleanly into 4 groups of 6 bits, and 24 divides evenly by both 8 and 6, which is exactly why the input/output ratio always lands on 3 bytes in, 4 characters out.

Padding: why some Base64 strings end in =

The clean 3-byte grouping above only works when your input length is a multiple of 3. Most real text is not, so Base64 needs a way to signal “this last group is short.” That’s what the = padding character does.

InputBytesBase64 outputWhy
”M”1TQ==1 byte can’t fill a 3-byte group, so it only produces 2 real characters, padded with ==
”Ma”2TWE=2 bytes produce 3 real characters, padded with one =
”Man”3TWFu3 bytes fill the group exactly: 4 characters, no padding needed

Each = you see at the end of a Base64 string is just filler marking how many bits were missing from that final group. It carries no data of its own.

Where you’ll actually see Base64

Base64 shows up anywhere binary or special-character data has to travel through a text-only channel. A few concrete cases:

HTTP Basic Authentication. The credentials user:pass1234 get encoded as dXNlcjpwYXNzMTIzNA== and sent in the header as Authorization: Basic dXNlcjpwYXNzMTIzNA==. This is literally how Basic Auth works, and it’s also a good reminder that Basic Auth carries no real protection on its own (see above) unless it’s running over HTTPS.

Embedding structured data in a payload or URL. A JSON object like {"id":42,"active":true} becomes eyJpZCI6NDIsImFjdGl2ZSI6dHJ1ZX0=, a flat string with no quotes or braces to escape, safe to drop into a URL query parameter or another JSON field.

Data URLs. CSS and HTML can inline a small image directly with data:image/png;base64,iVBORw0K... instead of a separate file request, which is why you’ll sometimes see a chunky Base64 blob sitting inside a stylesheet.

Email attachments. MIME, the format email uses for attachments, was designed decades ago around text-safe transport, so binary files get Base64-encoded before they’re stitched into the message body.

JWT tokens. A JSON Web Token is three Base64url segments separated by dots: header.payload.signature. The payload segment is just Base64url-encoded JSON, so a plain Base64/Base64url decoder, like the one below, will happily reveal it. (This isn’t a dedicated JWT decoder, it just decodes the segment you paste into it.)

Two more worked examples, useful for sanity-checking any decoder you’re working with:

“Hello, World!” encodes to SGVsbG8sIFdvcmxkIQ==.

“café” encodes to Y2Fmw6k=. That one is worth pausing on: “café” has 4 characters, but é takes 2 bytes in UTF-8, so the string is actually 5 bytes, not 4, and Base64 operates on bytes, never on characters. The same logic applies to an emoji like ”🚀”, which is 4 UTF-8 bytes on its own and encodes to 8J+agA==. If you ever see a Base64 output longer than you expected from the visible character count, multi-byte UTF-8 is almost always why.

Encode or decode your own text

Type into either widget below. Everything runs locally in your browser, nothing is sent to a server.

Base64 Encoder
Free, no sign-up, works on any device.
Open the full tool

Common mistakes and edge cases

Treating Base64 as encryption. This is worth repeating once, plainly: Base64 is not a security measure. It has no key, it’s fully reversible by design, and treating it as protection for a password, token, or personal data is a real anti-pattern, not a minor technicality. If it needs to stay secret, encrypt it; Base64 is not that layer.

Standard Base64 is not URL-safe. The +, /, and = characters can get mangled or cause ambiguity inside a URL, a query string, or a filename. That’s why a separate variant called Base64url exists, swapping + and / for - and _, and often dropping padding entirely. If you see a Base64-looking string in a URL or a JWT with no +, no /, and no =, that’s why: it’s the URL-safe variant, not a different encoding.

Whitespace or missing padding breaking a decode. Strict decoders can reject a string that has stray line breaks, spaces, or a padding character stripped off by whatever pasted it there. Clean the string first if a decode fails unexpectedly.

Multi-byte UTF-8 inflating the output more than expected. As shown above with “café” and ”🚀”, Base64 encodes bytes, not visible characters. Accented letters, CJK text, and emoji all take more than one byte each in UTF-8, so the encoded length reflects the byte count, not what you’d get from counting characters on screen.

Double-encoding by accident. Running an already-Base64 string through the encoder again produces a second layer of Base64 wrapped around the first. Decoding it once just gets you back the original encoded string, still gibberish, not the real content. If a decode looks like garbage, try decoding it a second time before assuming the string is corrupted.

Frequently asked questions

Is Base64 the same thing as encryption? No. Base64 is a reversible encoding with no key at all. Anyone can decode it in a single step with no special tools or knowledge. If you need to keep data secret, use actual encryption; Base64 only changes the representation, not the confidentiality.

Why does Base64 output look longer than the original text? Because it trades 8-bit bytes for 6-bit characters, so 3 bytes of input always turn into 4 characters of output, a fixed ~33% size increase. That overhead is the price of representing arbitrary bytes with a small, text-safe alphabet.

What do the = signs at the end of a Base64 string mean? They’re padding, added when the input length isn’t a clean multiple of 3 bytes. One = means the last group was short by one byte, == means it was short by two. They don’t encode any actual data, they just mark where the input ran out.

Why do some Base64 strings in URLs or JWTs have no +, /, or =? They’re using Base64url, a variant built specifically for URLs, filenames, and tokens like JWTs. It swaps the two characters that cause trouble in a URL (+ and /) for - and _, and commonly skips padding altogether.

Can I decode a JWT with a Base64 decoder? You can decode the header and payload segments, since both are just Base64url-encoded JSON separated by dots. Paste either segment (not the whole token, and not the signature part) into a Base64/Base64url decoder to read the claims inside.

Base64EncodingWeb DevelopmentAPIs
Base64 Encoder
Now try it yourself with the full tool.
Try it now
Related tools