How to use it
Type or paste into the box. It converts as you type, and nothing is uploaded.
- Choose Encode to turn text into Base64, or Decode to turn Base64 back into text.
- When encoding, pick the alphabet: Standard (+ / =) writes
+and/and pads with=; URL-safe (- _) writes-and_with no padding. Decoding reads either. - Press Copy next to the result, or Swap to move the result into the box and flip the direction.
The line under the result counts the bytes. When decoding it also says whether they’re UTF-8 text; if they aren’t, they’re shown as hex and Swap is disabled. Invalid Base64 gives one sentence saying what’s wrong, with the position of a bad character in the box.
Examples
HTTP Basic credentials, with Encode and Standard (+ / =):
Aladdin:open sesame
QWxhZGRpbjpvcGVuIHNlc2FtZQ==
The line under it reads 19 bytes of UTF-8, written as 28 Base64 characters. It’s RFC 7617’s example: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==.
The first segment of a JWT, with Decode:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{"alg":"HS256","typ":"JWT"}
JWT segments are URL-safe and unpadded, and they decode as they are.
An image as a data URL, with Decode:
data:image/png;base64,iVBORw0KGgo=
89 50 4e 47 0d 0a 1a 0a
The data: header is skipped. The 8 bytes are the PNG signature, which isn’t UTF-8.
Two Base64 strings pasted together, with Decode:
SGVsbG8=IHdvcmxk
The error is The "=" at position 8 isn't at the end, and Base64 padding only comes after the last character. Each half decodes alone (Hello and world), but = marks the end of the data, so encodings can’t be joined.
Good to know
- Base64 is defined in RFC 4648. Every 3 bytes become 4 characters of 6 bits each. A last group of 1 or 2 bytes becomes 2 or 3 characters, padded with
==or=in the standard alphabet. The output is about a third larger than the input. - The alphabets differ in two characters. Standard (section 4) uses
+and/, which mean something in URLs and paths; base64url (section 5) uses-and_.<<???>>encodes toPDw/Pz8+Pg==in one andPDw_Pz8-Pgin the other. - Text is encoded as UTF-8.
caféis 5 bytes and encodes toY2Fmw6k=. The browser’sbtoa("café")givesY2Fm6Q==because it treats each character as one Latin-1 byte, and it throwsInvalidCharacterErroron anything above U+00FF, emoji included. - Decoding is lenient where that’s safe. Spaces and line breaks are ignored, so MIME output wrapped at 76 columns (RFC 2045) decodes as pasted. Padding is optional.
- What it rejects: characters outside both alphabets,
=before the end, more than two=, padding that doesn’t complete a group of four, and a length that leaves one character over (Zm9vYhas 5). A%usually means it was URL-encoded (%3Dis=): URL-decode it first. - Bytes are shown as text only when they’re valid UTF-8, as
TextDecoderjudges it withfatal: true(WHATWG Encoding Standard). Anything else comes out as lowercase hex: most images, a cut-off or overlong character, a surrogate, or a byte that never appears in UTF-8, so+JCAgA==givesf8 90 80 80. Valid isn’t the same as readable:AA==passes as text, but that text is one NUL control character. - Spare bits aren’t checked.
QQ==andQR==both decode toA; RFC 4648 lets a decoder reject the second. - The encoder never inserts line breaks. Line breaks in the box are LF, one
0abyte each. Input is limited to 100,000 characters.
Questions
How do I decode Base64 to text?
Choose Decode and paste the string: the text appears below, or hex if the bytes aren’t UTF-8. Either alphabet works, padded or not.
How do I encode or decode Base64 in the terminal?
Run printf '%s' 'hello' | base64 to encode and base64 --decode to decode, on Linux or macOS. echo hello | base64 gives aGVsbG8K rather than aGVsbG8= because echo adds a newline. GNU base64 also wraps at 76 columns unless you pass -w 0.
How do I Base64-encode a string in JavaScript?
In Node.js, use Buffer.from(text, 'utf8').toString('base64'), or 'base64url' for the unpadded URL-safe form. In the browser, convert to UTF-8 first: btoa(String.fromCharCode(...new TextEncoder().encode(text))) matches this tool, though the spread fails on very long strings.
Why does Base64 end with = or ==?
The = is padding that fills the last group to four characters: one leftover byte gives ==, two give =. It carries no data, so URL-safe encoders, this one included, usually drop it; JWTs must leave it out.
Is Base64 encryption?
No: there’s no key, and anyone can decode it. It carries bytes through text channels like email, JSON and HTTP headers; Basic auth credentials and JWT payloads are readable by anyone who sees them.