Base64 Encoder & Decoder
Encode text to Base64, or decode Base64 back to text. Handles UTF-8 correctly, offers base64url, and tells you when the result is binary rather than pretending it is text.
text
base64
SGVsbG8sIHdvcmxkIQ==
Encoded: SGVsbG8sIHdvcmxkIQ==
Runs in this browser tab. Nothing is uploaded, and the text is not stored or logged. Base64 is an encoding, not encryption — anything you put through it can be read back by anyone.
How to use this tool
Base64 turns arbitrary bytes into 64 printable ASCII characters, so binary data can survive channels that only handle text: email, JSON, cookies, URLs, environment variables. It does that by spending four characters for every three bytes, which is where the inflation comes from.
- 1Pick `encode` to turn text into Base64, or `decode` to turn it back.
- 2For encoding, tick `base64url` if the result is going into a URL, a JWT, or a filename, and set a wrap width if you need PEM or MIME line breaks.
- 3Copy or download the result. Nothing leaves your browser either way.
Base64 is not encryption
This is the single most important thing to know about Base64, and it is the reason this page says it in three places. Base64 is an encoding. There is no key, no secret, and nothing to keep safe. Every Base64 string can be turned back into what it was by anyone, using a tool like this one, in about a second.
It is genuinely useful for moving data through text-only channels, and it is genuinely useless for hiding it. If you need something to be confidential, it needs to be encrypted — HTTPS, or encryption designed for the job.
How the alphabet works
There are 64 printable characters used as digits: A–Z, a–z, 0–9, then `+` and `/`. Every three bytes of input become four characters, and the leftover bytes are padded with `=` to the end.
"Hel" -> SGVs
"llo" -> bGxv (three groups, no padding)
"lo!" -> bG8= (two bytes left, so one = pads the group)That padding is why a Base64 string's length is always a multiple of four, and why one that is not was truncated somewhere in transit.
base64url, and when you need it
Standard Base64 uses `+` and `/`, and both are awkward in a URL: `+` is read as a space in a query string, and `/` is read as a path separator. Base64url swaps those two characters for `-` and `_` and drops the padding, which makes the result safe to drop into a URL, a JWT, or a filename unescaped.
Worth knowing, because it surprises people: for plain ASCII text the two encodings are identical apart from the padding. The `-` and `_` characters only ever appear when the input contains bytes above 127, so a text-only string will not show you the difference at all.
Line wrapping
Long Base64 strings are often broken into lines, because some channels cannot hold a single unbroken line of text. Both common widths are multiples of four — 76 for MIME (an email attachment) and 64 for PEM (a certificate or key) — so each line can be decoded on its own.
This decoder ignores whitespace entirely, so it reads wrapped input, unwrapped input, and input with the two mixed, without complaint.
When the result is not text
A Base64 string can hold any bytes at all, and many of the things people decode are files rather than text: an image, a font, a compressed archive, a private key. Those bytes are not valid UTF-8, so there is no honest way to show them as characters.
Rather than display replacement characters and let you copy something that no longer matches the input, this page says so and shows the bytes as hex. To get the real file back, decode it to bytes rather than to text:
echo 'iVBORw0KGgoAAAANSUhEUg==' | base64 -d > image.png
# -d decodes to bytes. Without it, base64 writes the decoded text and
# corrupts anything that is not valid UTF-8.Doing it by hand
Worth doing once, because it makes clear there is nothing magic happening. In a terminal, `base64` and `base64 -d` are the whole story:
echo -n 'Hello, world!' | base64 # SGVsbG8sIHdvcmxkIQ==
echo -n 'Hello, world!' | base64 -d # Hello, world!
echo -n 'Hello, world!' | base64 | base64 -d # round trip
# Node, if you would rather not leave the terminal
node -e 'console.log(Buffer.from("hi").toString("base64"))'One trap in the shell version: `echo` adds a trailing newline, so `echo 'hi' | base64` encodes two characters rather than one. Use `echo -n` when the exact bytes matter.
Frequently asked questions
- Is Base64 encryption?
- No. It is an encoding, and anyone can reverse it with a tool like this one. Encoding something here does not make it confidential — it never was. Use encryption if you need secrecy.
- What is base64url, and do I need it?
- The same encoding with `+` and `/` replaced by `-` and `_`, and the padding dropped, so the result is safe in a URL unescaped. You need it for JWTs, query strings, and filenames. For plain ASCII text it differs from standard Base64 only in the padding.
- Why does my decoded output show hex?
- Because the bytes are not valid UTF-8, so there is no text to show. That normally means the input was a file rather than a string. The Base64 was fine; the page is declining to invent characters. Use `base64 -d` in a shell to recover the original file.
- Why is there no padding on my string?
- Base64url drops it, and so does anything that decoded a JWT. A standard Base64 string is always a multiple of four characters. If yours is not, part of it was lost in copying — this page will say so rather than guessing.
- Does this send my data anywhere?
- No. Both directions run in your browser tab. Nothing is uploaded, stored, or logged.