How to use this Base64 Encoder Decoder
Paste text into the input box, then choose whether you want to encode or decode it. The
result appears instantly in the output area, and you can copy or download it for use in
your workflow.
- Paste plain text or Base64 text into the input box.
- Click Encode to convert text to Base64.
- Click Decode to convert Base64 back to readable text.
- Copy, swap, or download the result as needed.
Example encode result
Hello ToolzYard
↓
SGVsbG8gVG9vbHpZYXJk
Common use cases
- API payload testing
- Basic auth header values
- Data URLs
- Token inspection
- Text-safe transport
Why Base64 makes your data about a third bigger
Base64 takes three bytes at a time — 24 bits — and rewrites them as four characters
drawn from a fixed 64-symbol alphabet (A–Z, a–z,
0–9, plus + and /). Each output character carries
exactly 6 bits, so four of them hold the same 24 bits that three raw bytes did. That 4:3
ratio is where the well-known overhead comes from: encoding inflates the payload by
roughly 33%. Ship 300 KB of binary data and you transmit about
400 KB of Base64.
When the input length is not a multiple of three, the encoder pads the final group with
one or two = characters so the output length stays a multiple of four. The
= is length padding, not part of your data — the decoder uses it to work out
how many bytes the last group really held. This inflation is easy to forget until it
bites: a Base64 data: URI in your CSS is a third larger than the file it
carries and can no longer be cached as a separate resource, so inlining a big image
often makes a page slower, not faster.
Base64 is encoding, not encryption
This is the single most important thing to understand about Base64: it provides
zero confidentiality. It is a reversible mapping with a public, fixed
alphabet, so anyone who sees the string can decode it in a fraction of a second with no
key. Base64 hides nothing.
A Basic Auth header (Authorization: Basic ...) is nothing more than
base64(username:password) — it is only as safe as the TLS wrapping the
request, and over plain HTTP it is effectively plaintext. The same applies to JWTs: the
header and payload are Base64-encoded, not encrypted, so anyone can read a token's
claims. Only the signature protects it, and only against tampering, not against reading.
If you ever find yourself Base64-encoding a value to "hide" it, what you actually want is
encryption.
The btoa() bug that catches everyone: non-Latin1 text
JavaScript's built-in btoa() only accepts characters in the Latin-1 range
(code points 0–255). Hand it an emoji, a Chinese character, or even a curly quote and it
throws:
Failed to execute 'btoa': The string to be encoded contains characters outside of
the Latin1 range. The cause is that btoa() works one byte per
character and assumes every character fits in a single byte — false for anything above
U+00FF.
The fix is to convert the text to bytes first. The classic one-liner is
btoa(unescape(encodeURIComponent(str))), which UTF-8 encodes the string
before Base64 — this is what this tool does. The modern, non-deprecated equivalent uses
new TextEncoder().encode(str) to get a UTF-8 Uint8Array, then
Base64s those bytes. Either way the rule is the same: Base64 encodes bytes, so
decide your text's byte encoding — almost always UTF-8 — before you encode, and decode
with the same assumption on the other side or you will get mojibake.
base64url: the variant for URLs, filenames, and JWTs
Standard Base64's alphabet includes + and /, and both are
dangerous in the wrong place. / is the path separator in URLs and file
paths; + is decoded as a space in
application/x-www-form-urlencoded form data. Drop a standard Base64 string
into a query parameter and a + inside it can silently become a space,
corrupting the value.
base64url (RFC 4648 §5) fixes this by swapping two characters:
- replaces +, and _ replaces /. It
also usually drops the = padding, since = itself needs
percent-encoding in a URL. This is the encoding JWTs use for every segment. If you paste
a JWT payload into a standard Base64 decoder and it fails, the culprit is almost always
an unconverted - or _, or missing padding: convert
- back to +, _ back to /, and re-add
= until the length is a multiple of four.
Don't treat a Base64 string as a fingerprint
A subtle trap: the same bytes can have more than one valid-looking Base64 spelling.
Most decoders are lenient about the unused bits in the final padded group, so two
strings that differ only in those trailing bits can decode to identical data. On top of
that, whitespace and line breaks are ignored by most decoders — Base64 was historically
wrapped at 76 columns for email (MIME), so the same content might arrive with or without
newlines.
Because of this, never compare two Base64 strings to test whether their contents are
equal, and never use a Base64 string as a checksum or cache key. Decode both sides
first, then compare the raw bytes — or, if you need a real identity check, hash the
decoded data.
Frequently Asked Questions
Why is my Base64 output longer than the input?
Because Base64 rewrites every 3 bytes as 4 characters, output is about 33% larger
than the input, plus one or two = padding characters when the length
isn't a multiple of three. That is expected — Base64 trades size for text safety, so
it is a poor choice when bandwidth or storage is tight.
Why does btoa() throw "characters outside of the Latin1 range"?
btoa() only handles characters 0–255, so any emoji or non-Latin
character breaks it. Convert the text to UTF-8 bytes first — e.g.
btoa(unescape(encodeURIComponent(str))) or with
TextEncoder. This tool already does the UTF-8 step for you.
Does Base64 encrypt or protect my data?
No. Base64 offers zero confidentiality. It uses a public, fixed alphabet, so anyone
can decode it instantly with no key. Use real encryption for secrecy and TLS
(HTTPS) for data in transit; Base64 only changes the representation.
What's the difference between Base64 and base64url?
base64url swaps the two URL-unsafe characters: - for + and
_ for /, and usually drops = padding. It is
used in JWTs, query parameters, and filenames, where standard Base64's +
and / would be corrupted or need escaping.
What are the = signs at the end for?
They are padding that keeps the encoded length a multiple of four. One or two
= signals that the final group encoded only two bytes or one byte,
respectively. They carry no data of their own — a decoder uses them to reconstruct
the exact byte count.
Why won't my JWT segment decode with a normal Base64 decoder?
JWT segments are base64url, not standard Base64. Convert - back to
+ and _ back to /, then re-add =
until the length is a multiple of four before decoding.