Free online Base64 decoder
Base64 decode that names what it found
Paste a Base64 string and the payload appears at once — as UTF-8 text, as indented JSON, as an image preview, or as a file with the right extension on the download button. The decoder is free and needs no account, it takes up to 5 MB of Base64 (3.75 MB of decoded bytes), and it copes with the URL-safe alphabet, absent = padding and the line breaks in a wrapped block without a setting to touch. When a string is not Base64 at all it says which character stopped it and where that character sits, instead of handing back an empty box.
- 100% free
- No signup
- 5 MB of Base64
- URL-safe alphabet
- Padding repaired
The decoded payload lands here.
Paste a string, drop a .txt of Base64, or press Ctrl+V anywhere on this page.
How to decode a Base64 string
Paste, read, take it away — three steps and no account in the way.
Paste the string
Drop it into the left box, or hit the paste shortcut anywhere on the page — ⌘V on a Mac, Ctrl+V elsewhere. A whole data: URI can go in exactly as copied; the data:image/png;base64, part is recognised and set aside. Wrapped blocks from an email header or a PEM file are fine too, because line breaks are removed before anything is decoded.
Read what came back
The right-hand pane names the payload before it shows it: UTF-8 text, JSON re-indented with two spaces, an SVG or PNG rendered as a picture, a gzip stream inflated on the spot, or a 16-bytes-per-row hex dump when the bytes are opaque. Underneath, a line reports how many Base64 characters went in, how many bytes came out, and every repair that was applied on the way.
Take the text or the file
Copy lifts the decoded text to the clipboard. The download button carries the extension it is about to use — .json, .png, .pdf, .gz — because the extension comes from the magic number in the decoded bytes rather than from whatever produced the string. Copy is switched off for payloads that are not text, since a PNG on the clipboard as characters helps nobody.
Technical specifications
| Accepted alphabets | Standard RFC 4648 §4 (+ and /) and URL-safe §5 (- and _), detected automatically; a string that mixes the two is rejected rather than guessed at |
|---|---|
| Padding | Optional — a 4n+2 string gets == back and a 4n+3 string gets =, with the repair reported; 4n+1 is rejected as truncated, and surplus = signs are ignored |
| Whitespace | Spaces, tabs, CR and LF are stripped before decoding, so a 76-column MIME block, a PEM body or a wrapped email header pastes in as it stands |
| Wrappers unpacked | data:<type>;base64, URIs, with the declared media type carried through to the download; three-segment JWTs split into header and payload |
| Maximum input | 5 MB of Base64 (5,242,880 characters), which carries 3,932,160 bytes — 3.75 MB — and decodes in about 30 ms |
| Payloads recognised | UTF-8 text, JSON, XML, SVG, PNG, JPEG, GIF, WebP, BMP, ICO, PDF, gzip, ZIP, WOFF and WOFF2, MP3, Ogg and MP4 — matched on the leading bytes, never on a file name. gzip is inflated where DecompressionStream exists (Chrome 80, Firefox 113, Safari 16.4 and later); anything still opaque becomes a hex dump of the first 384 bytes |
| Invalid input | Reported as the character itself, its U+ code point and its 1-based position in what you pasted — an en dash from a word processor is named as an en dash, not as “invalid character” |
| Price and processing | Free, with no account and no daily quota; the decoding runs on your own machine, so no string is uploaded |
Frequently asked questions
Why does my decoded text come back as é instead of é?
Because something read the decoded bytes as Latin-1 when they are UTF-8. The browser's own atob() hands back one character per byte, so the pair C3 A9 that spells é surfaces as à followed by ©, and the four bytes of an emoji surface as ð plus three invisible control characters. This page never takes that shortcut: the bytes go through TextDecoder in UTF-8 mode, so é is é and 😀 is one emoji. When a byte run is not valid UTF-8 at all, you get a hex dump and a note saying so, rather than a page full of replacement characters.
My string has - and _ in it. Is that still Base64?
Yes — that is base64url, the alternative alphabet in RFC 4648 §5, where - stands in for + and _ for /. It exists because + and / already mean something inside a URL and a filename: + is a space in a query string and / is a path separator, so a plain Base64 value pasted into a link arrives at the server mangled. This decoder spots either alphabet on its own and tells you which one it found. What it will not do is decode a string containing both, since one of the two markers must then be corruption and picking a winner would hand you wrong bytes with no warning.
Can I decode Base64 with no = signs at the end?
Yes, and it is the common case for tokens and URLs. Padding carries no data — it only rounds the final group up to four characters, so a decoder can work out from the length alone that a 4n+2 string is short by two = and a 4n+3 string by one. This page adds them back silently and says it did. The one length that cannot be repaired is 4n+1: no combination of bytes produces a single leftover character, so that string lost something in transit.
How does the tool know the result is a PNG and not text?
It reads the first bytes of the decoded output and compares them against known file signatures. A PNG opens with 89 50 4E 47, a JPEG with FF D8 FF, a PDF with the literal %PDF-, a gzip stream with 1F 8B, a ZIP with 50 4B 03 04, and a WOFF2 font with the ASCII wOF2. Signatures are checked before any attempt at text, because a file whose bytes happen to be valid UTF-8 is still a file. Only when nothing matches does the decoder try UTF-8, and only then does it look at whether the text is JSON, markup or prose.
Is Base64 encryption?
No, and nothing encoded in it is protected in any way. Base64 is a reversible transport encoding with no key and no secret: this page decodes it, so can every language's standard library, so can anyone who intercepts it. A password sitting in a Base64 header is a password in plain sight — HTTP Basic auth is exactly that, which is why it is only acceptable over TLS. If the output is still unreadable after decoding, you are holding ciphertext or a compressed stream rather than text; ciphertext has no recognisable structure, while gzip announces itself with 1F 8B and gets inflated here automatically.
What does “length 4n+1” mean when the decoder rejects my string?
It means the string cannot be the output of any Base64 encoder, because encoders emit characters in groups: 3 bytes make 4 characters, 2 bytes make 3, 1 byte makes 2. A remainder of exactly one character is unreachable. In practice something ate a character — a copy that stopped one short, a spreadsheet cell that trimmed the value, a log line cut at a column limit. The error names the length so you can compare it against the source rather than guessing.
Can I paste a whole JWT into a Base64 decoder?
Here, yes: a token with three dot-separated segments is recognised, and its header and payload are decoded from base64url and shown as indented JSON. Most decoders reject it, and correctly so — the dots are not Base64 characters, so a JWT is three Base64 strings rather than one. What no decoder can do is tell you whether the token is genuine, because verifying an HS256 or RS256 signature needs the key. Reading the claims and checking how long exp has left belongs on the JWT decoder page.
About decoding Base64
Decoding is arithmetic before it is anything else. Base64 reads four characters, looks each one up in a 64-entry table to recover 6 bits, and glues the 24 bits back into 3 bytes; the = signs at the end say the last group was short, so one or two of those bytes are dropped. Nothing else is encoded — not the character set of the text, not the type of the file, not the byte order. That is why a decoder can only ever hand you bytes, and why the interesting work starts after the arithmetic: deciding whether those bytes are a sentence, a JPEG or a compressed stream.
The second thing to know is that there is more than one Base64. RFC 4648 §4 defines the alphabet everyone means by default, ending in + and /; §5 defines base64url, swapping those two for - and _ so a value survives a query string; and the older MIME rules in RFC 2045 insist on breaking the output into lines of at most 76 characters and tell the decoder to ignore anything outside the alphabet. Implementations disagree about how forgiving to be, which is where the surprises come from: Python's base64.b64decode quietly discards stray characters unless you pass validate=True, Go's StdEncoding returns CorruptInputError with an offset, and the browser's atob tolerates whitespace but refuses base64url outright. This page accepts everything unambiguous and explains every repair, so what you see is what a strict decoder would have needed. The encoder on the other side of the pair lets you produce each of those variants deliberately.
In practice the string in your clipboard is rarely just text. It is a data: URI lifted out of a stylesheet, a JWT from an Authorization header, a gzip blob from a log pipeline, a PDF an API returned as a field in JSON, or an avatar someone stored in a database column. Each of those needs a different thing done to it once the bytes exist, which is why this page identifies the payload before it prints anything, and why a document that turns out to start with %PDF- is better rebuilt with the Base64-to-PDF page, which checks the header and previews the first page before you save it.
Where your string is decoded
The decoding runs inside this tab. Your string is turned into bytes by JavaScript on your own machine, previewed there and downloaded from there, so nothing is uploaded and nothing is logged — which matters more here than on most pages, because the thing people decode is so often a token or a credential. Close the tab and the payload is gone with it.