Base64 Encoder and Decoder
Paste text or Base64 and convert it instantly, in your browser.
Runs entirely in your browser
Loading the tool…
Base64 turns arbitrary bytes into 64 printable characters so they survive systems
that only expect text: email bodies, JSON fields, data URIs, JWT payloads and
HTTP Authorization headers. It is an encoding, not encryption:
anybody can decode it, including this page.
This decoder accepts standard and URL-safe alphabets, with or without
= padding, and ignores line breaks, so you can paste a wrapped
certificate block or a header value straight in.
How to use it
- Paste your text or Base64 string into the box.
- Pick Encode or Decode. The result appears as you type.
- Press Copy to put the result on your clipboard.
Questions
Is Base64 encryption?
No. Base64 is reversible by anyone with no key at all. Use it to move data safely through text-only channels, never to hide it. For actual secrecy, encrypt the data first.
Why does my decoded text look like gibberish?
The original bytes were probably not text at all: an image, a compressed file or a binary protocol message. Base64 decoding gives you the bytes back, but only UTF-8 text can be shown as characters.
What is URL-safe Base64?
A variant that uses - and _ instead of + and /, so the result can sit inside a URL or filename without escaping. This tool detects and accepts both automatically.
Does my data get uploaded?
No. The conversion runs as WebAssembly inside your browser tab, so what you paste never leaves the device.
How much bigger does Base64 make a file?
About a third. Every 3 bytes become 4 characters, so a 1 MB image is roughly 1.37 MB as a data URI, and more once a mail client wraps it. Worth knowing before you inline an asset to save a request: below about 4 KB it usually pays, above it usually does not.
Why does my Base64 have line breaks in it?
Because it came out of a system with a line limit. MIME wraps at 76 characters, PEM certificate blocks at 64. Both are ignored here, so a wrapped block pastes in and decodes without cleaning it up first.
Can I decode a JWT with this?
The header and payload are URL-safe Base64 and will decode into readable JSON. The signature is raw bytes and comes out as noise, which is expected rather than a fault. The JWT decoder splits the three parts for you and formats the claims.
Some encoders leave off the = signs. Is that valid?
It is common and usually fine. The padding carries no information; a decoder can work out the length from the number of characters. JWTs strip it by specification. Some strict parsers still insist on it, which is why this page accepts both.
The alphabet, and a worked example
Base64 reads three bytes, 24 bits, and rewrites them as four six-bit numbers, each
one an index into a 64-character alphabet. Indices 0 to 25 are A to
Z, 26 to 51 are a to z, 52 to 61 are
0 to 9, and the last two are + and
/ in the standard alphabet, or - and _ in the
URL-safe one.
Encoding the word Man is the whole algorithm in one line:
| Step | Value | |||
|---|---|---|---|---|
| Text | M a n | |||
| Bytes | 77 97 110 | |||
| Bits | 01001101 01100001 01101110 | |||
| Regrouped by six | 010011 | 010110 | 000101 | 101110 |
| As numbers | 19 | 22 | 5 | 46 |
| Base64 | T | W | F | u |
When the input does not divide by three, the last group is padded with
= so the output still comes in fours: Ma encodes to
TWE= and M alone to TQ==. One equals sign
means the final group held two bytes, two means it held one, and three equals signs
is not a thing that can happen.
The cost is fixed: four characters for every three bytes, so Base64 data is about 33% larger than what went in, before any line breaks. That is the number to keep in mind before inlining an image as a data URI.
The other direction
Encoding has a page of its own, opening the right way round:
Your data stays on your device
Everything above runs inside your browser as WebAssembly compiled from Rust. Nothing you type is uploaded, logged or stored on a server. You can load this page once, go offline, and it still works.
This page makes no requests at all, to anywhere. That is not a promise in the copy: it is a Content-Security-Policy header your browser enforces, and connect-src on it is none. Open the network tab and watch nothing happen.