Skip to content

Base64 Encoder & Decoder

Encode or decode Base64 and Base32 instantly, including images as data URIs with a live preview of the result. Everything happens in your browser — unlike the leading alternatives there is no upload path at all, so there is no file retention policy to read.

Format

Runs in your browser. Nothing uploaded.

How to use it

  1. Choose encode or decode. Encode turns text or a file into Base64. Decode turns Base64 back.
  2. Type, paste, or drop a file. Files are read with the browser’s FileReader, so nothing is uploaded and we impose no size cap.
  3. Set the options if you need them. URL-safe swaps the two characters that break inside a URL. Wrap adds line breaks every 76 characters for email. Data URI wraps the output ready to paste into HTML or CSS.
  4. Copy or download. “Use output as input” flips the direction, which is handy for checking a round trip.

What Base64 is

Base64 represents binary data using 64 printable ASCII characters: A–Z, a–z, 0–9, plus + and /, with = for padding. That’s it. Every byte sequence in the world can be written using those characters.

It exists because a lot of systems only handle text safely. Email bodies, JSON payloads, XML documents, HTTP headers, and URLs all have characters that mean something structural. Push raw binary through them and something will misinterpret a byte as a delimiter, a control character, or an end-of-line. Base64 sidesteps that by using only characters nothing objects to.

The cost is size. Base64 output is always about 33% larger than the input, because it packs 3 bytes into 4 characters. That trade is usually worth it for small payloads and rarely worth it for large ones.

Is Base64 encryption? No.

This is the single most consequential misunderstanding about Base64, so it gets its own section.

Base64 is an encoding. Encryption requires a key and is designed to be unreadable without it. Base64 requires nothing — every browser, every language and this page can decode it instantly. It offers exactly zero protection.

What that means in practice: never Base64 a password, an API key, a token or personal data and treat it as hidden. It is not hidden. It is the same data wearing a hat. Security scanners flag Base64-obscured secrets in source control constantly, and they are right to.

Where Base64 legitimately appears next to security is as a transport format for things that are already protected. HTTP Basic Auth Base64-encodes the credentials, but the protection there comes from TLS, not from the encoding. JWTs Base64url-encode their header and payload, and anyone can read them — the signature is what makes them trustworthy, not the encoding. If you decode a JWT and are surprised you can read it, that is working as designed.

How the Base64 encoder works

Base64 takes three bytes at a time — 24 bits — and splits them into four groups of six bits. Six bits gives 64 possible values, which is where the name comes from. Each value maps to one character in the alphabet.

Take the three characters Man:

Step M a n
ASCII value 77 97 110
8-bit binary 01001101 01100001 01101110
Regrouped into 6 bits 010011 010110 000101 101110
Decimal 19, 22, 5, 46
Base64 character T, W, F, u

Man becomes TWFu. Three bytes in, four characters out.

When the input isn’t a multiple of three, the last group is short. Base64 pads it with zero bits and then appends = characters to record how much was padding. One leftover byte produces two =, two leftover bytes produce one =. That’s why so much Base64 ends in = or == — it’s a length marker, not data.

Padding is why Zg== is f, Zm8= is fo, and Zm9v is foo with no padding at all. Those come from RFC 4648’s test vectors, and this tool is tested against every one of them.

URL-safe Base64

Standard Base64 uses + and /. Both are a problem in a URL: + means a space in query strings, and / is a path separator. Put standard Base64 in a URL and something downstream will mangle it.

RFC 4648 §5 defines a URL-safe variant that swaps + for - and / for _. Padding is often dropped too, since = also needs encoding in a query string. This is the variant JWTs use, which is why JWT segments contain hyphens and underscores but never slashes.

Decoding here accepts either alphabet automatically, and adds back missing padding, so you can paste a JWT segment straight in without thinking about it.

Files, images and data URIs

A data URI embeds a file directly in a document instead of linking to it. The format is data:, the MIME type, ;base64,, then the payload.

Drop an image in with “Output as data URI” ticked and you get something you can paste straight into an img tag or a CSS background-image. The browser decodes it without a network request, which removes a round trip.

That’s the upside. The downsides are real and worth knowing before you commit:

  • Roughly a third larger. A 9KB icon becomes about 12KB of text.
  • It cannot be cached separately. The bytes are part of the document, so every page load carries them again.
  • It bloats the file it lives in. A large data URI in a stylesheet blocks rendering until the whole stylesheet parses.

The rule of thumb most teams settle on: data URIs suit small icons and tiny images used once. Photographs and anything reused across pages should stay as files.

Images: both directions, with a preview

Drop an image anywhere on the tool, or press “Choose a file” if you’d rather not drag. You get the Base64 immediately, and ticking “Output as data URI” wraps it into a data: URL you can paste straight into CSS or an img tag.

Going the other way works too: switch to Decode, paste a data URI, and the picture appears. Either direction shows the preview, which is the only way to be sure the bytes survived the trip — a truncated Base64 string still decodes to *something*, and a preview tells you instantly whether that something is your image.

<img src="data:image/png;base64,iVBORw0KGgoAAAANS..." alt="">

.icon {
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxu...");
}

The prefix matters. data:image/png;base64, tells the browser what it’s looking at, and getting the MIME type wrong is the usual reason a data URI renders as a broken image. The tool fills it in from the file you gave it.

Worth knowing before you inline everything: a data URI is about 33% larger than the file, it can’t be cached separately, and it blocks the stylesheet it lives in until it’s parsed. It’s a good trade for a 2KB icon and a bad one for a 200KB photograph.

Base32: same job, different alphabet

Switch the format toggle and the same input encodes to Base32 instead.

Base64 Base32
Symbols 64 32
Bits per character 6 5
Size overhead ~33% ~60%
Case sensitive Yes No
foobar becomes Zm9vYmFy MZXW6YTBOI======

Base32 is bigger, so why use it? Because a human can handle it. The alphabet is A–Z and 2–7 only: case doesn’t matter, and 0, 1 and 8 are deliberately absent because they’re too easily confused with O, I and B.

That makes it safe to read aloud down a phone, write on paper, or put somewhere case gets flattened. Which is why you meet it in TOTP two-factor secrets, Tor onion addresses, and licence keys — all places where someone types the string by hand.

If the tool rejects your Base32, look for a 0, a 1 or an 8. It’s almost always someone reading O as zero when copying by hand, and the error message says so.

Base64 to hex, and other conversions

There’s no direct Base64-to-hex operation, and any tool offering one is doing the same two steps you would: decode to bytes, then re-encode.

Both formats are just ways of writing the same bytes down. So the route is always through the bytes:

Base64  →  bytes  →  hex
                  →  binary
                  →  decimal
                  →  text

Decode here, then paste the result into the hex, binary and ASCII converter, which shows every representation at once. The same applies to “base 64 to text”, which is just decoding with no second step.

Worked examples

Encoding text with accents. Encode héllo and you get aMOpbGxv. Note it isn’t 5 characters of input producing a tidy result — é is two bytes in UTF-8, so the input is 6 bytes and the output is 8 characters.

This is where naive implementations break. JavaScript’s built-in btoa throws an error on any character above U+00FF, and silently mangles some of what it does accept, because it operates on Latin-1 rather than UTF-8. This tool converts through TextEncoder first, so emoji and CJK text round-trip correctly.

Decoding a JWT payload. Take the middle segment of a token — the part between the two dots — and paste it in with decode selected. You get readable JSON: the claims, the issuer, the expiry. No key required, which is exactly the point made earlier.

Checking a round trip. Encode something, press “Use output as input”, and decode. If you don’t get the original back exactly, something in your pipeline is corrupting the data — usually a character-set conversion happening somewhere you didn’t expect.

Doing it elsewhere

Environment Encode Decode
Shell base64 file.txt base64 -d file.b64
JavaScript (ASCII) btoa(str) atob(str)
JavaScript (Unicode) btoa(String.fromCharCode(...new TextEncoder().encode(str))) new TextDecoder().decode(Uint8Array.from(atob(s), c => c.charCodeAt(0)))
Python base64.b64encode(data) base64.b64decode(data)
PHP base64_encode($data) base64_decode($data)

Note the shell command adds a trailing newline and wraps long output; use base64 -w 0 on GNU coreutils if you need one unbroken line.

Common mistakes

Using btoa on Unicode text. The most frequent Base64 bug in JavaScript. It fails loudly on emoji and quietly on some accented characters. Always encode to UTF-8 bytes first.

Forgetting that Base64 is bigger. If you Base64 a payload to put it in JSON, budget for the 33% increase. Teams have hit request-size limits this way.

Standard Base64 in a URL. Works in testing, breaks the moment a value happens to contain + or /. Use the URL-safe variant from the start.

Assuming padding is optional. Some decoders require it, some don’t. Strip it only if you know the other end tolerates that — JWT does, many libraries don’t.

Treating it as obfuscation. Covered above, and worth repeating because it keeps happening: it hides nothing from anyone.

Where you’ll actually meet Base64

It’s worth recognising Base64 in the wild, because it turns up in more places than most people expect and knowing which variant you’re looking at saves time.

Email attachments. MIME encodes attachments as Base64 wrapped at 76 characters per line. That line length isn’t arbitrary — it comes from SMTP’s limits on line length, and it’s why the “wrap” option exists here.

PEM certificates and keys. Anything between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- is Base64-encoded DER, wrapped at 64 characters. If you’ve ever wondered what’s inside a .pem file, decoding it gives you the binary structure, though you’ll want a certificate parser to read that.

JSON Web Tokens. Three URL-safe Base64 segments separated by dots: header, payload, signature. The first two decode to readable JSON. Try it — paste a token’s middle segment into the decoder. What you should take from that is how little a JWT hides.

HTTP Basic Authentication. The header is literally Basic followed by Base64 of username:password. It’s a wire format, not protection, which is why Basic Auth over plain HTTP is unacceptable — anyone watching the connection reads the credentials as easily as you would.

Data URIs in CSS and HTML. Small inline images, covered above.

Docker config and Kubernetes secrets. Kubernetes Secrets store values Base64-encoded, which regularly misleads people into thinking they’re encrypted. They aren’t. kubectl get secret -o yaml plus a Base64 decode gives you the plaintext. Encryption at rest is a separate setting you have to switch on.

The pattern across all of these: Base64 shows up wherever binary needs to travel through a text channel. It never shows up as a security measure, though it’s frequently mistaken for one.

Common questions about size and performance

Why exactly 33% larger? Four output characters carry three input bytes, so the ratio is 4/3. Padding adds up to two more characters, and line wrapping adds a newline every 76 characters. For a 1MB file, expect roughly 1.37MB of Base64.

Does Base64 compress well? Yes, surprisingly well — gzip typically claws back most of the expansion, because Base64 output has far less entropy per character than the binary it represents. If your Base64 travels over a compressed HTTP response, the overhead on the wire is much smaller than the raw figure suggests. It’s still there in memory and in storage.

Is it slow? Not meaningfully. Encoding is a straightforward bit-shuffle with no arithmetic to speak of. The cost you’ll notice with a large file is reading it into memory, not the encoding itself.

How large a file can this handle? There’s no limit imposed by us, because nothing is uploaded. The practical ceiling is your browser’s memory: the file is read into an array buffer and the Base64 string is built alongside it, so budget roughly 2.5 times the file size in RAM. Files in the tens of megabytes are comfortable on a normal machine; a multi-gigabyte file is not.

Related tools

A JWT is three Base64url segments, so the JWT decoder will read one straight off without you decoding each part by hand. For percent-encoding rather than Base64 — the other thing people reach for when a value breaks a URL — use the URL encoder. And if you need a checksum rather than an encoding, the hash generator covers MD5 through SHA-512.

Frequently asked questions

What is Base64 encoding?

Base64 represents binary data using 64 printable ASCII characters. It exists so that binary can travel safely through systems that only handle text, such as email bodies, JSON payloads and data URIs. Every 3 bytes of input become 4 characters of output, which is why Base64 is always about 33% larger than the original.

Is Base64 encryption?

No, and this matters. Base64 is an encoding, not encryption. Anyone can decode it instantly with no key — including this page. Never use it to hide passwords, tokens or personal data. If you need something kept secret, you need encryption.

How do I Base64 encode a file?

Drop the file onto the input area above. It is read with the browser FileReader API, so the bytes stay on your machine and there is no upload and no size limit imposed by us. Very large files are limited only by your available memory.

How do I encode an image as a data URI?

Drop the image in and switch on "Output as data URI". You get a complete data: URL with the correct MIME type, ready to paste into an img src or a CSS background-image. Note that data URIs are roughly a third larger than the file, so they suit small icons better than photographs.

What is URL-safe Base64?

Standard Base64 uses + and / which both have meaning inside a URL. URL-safe Base64 (RFC 4648 §5) replaces them with - and _ so the value survives being put in a query string or path. JWTs use this variant. Tick "URL-safe" to produce it; decoding accepts either form automatically.

How do I do this in the terminal, JavaScript or Python?

In a shell, base64 file.txt encodes and base64 -d encodes back. In JavaScript, btoa and atob work for ASCII but corrupt non-Latin-1 text, so route it through TextEncoder first. In Python, use the base64 module: base64.b64encode(data) and base64.b64decode(data).

How do I convert an image to Base64, or back again?

Drop the image anywhere on the tool, or press "Choose a file". Tick "Output as data URI" to wrap it as a data: URL you can paste straight into CSS or an img tag. Going the other way, switch to Decode and paste the data URI — the prefix is stripped for you. Either direction shows a preview of the image underneath, so you can confirm it survived.

What is Base32 and when would I use it?

Base32 does the same job with a 32-symbol alphabet, so five bits per character instead of six. That makes it about 60% larger than the original where Base64 is 33% larger. The trade is worth it when a human has to handle the string: the alphabet is case-insensitive and leaves out 0, 1 and 8 because they look like O, I and B. That is why it turns up in TOTP secrets, onion addresses and licence keys.

Why is my Base32 string rejected?

Almost always a 0, 1 or 8. They are not in the alphabet, and the usual cause is someone reading O as zero or I as one when copying by hand. Padding is optional here and case does not matter, so those are not the problem.

How do I get from Base64 to hex?

Decode it here first, then paste the result into the hex, binary and ASCII converter. Base64 and hex are both ways of writing bytes as text, so the route is always through the bytes themselves rather than directly between the two representations.

Guides that use this tool

Last updated: August 18, 2026