Base64 Encode / Decode
Encode text to Base64 or decode Base64 strings back to plaintext. Supports full UTF-8 characters.
Result will appear here...
TL;DR
Base64 is encoding, not encryption. It is fully reversible by anyone with no key — treat a Base64 string as if it were plaintext. It packs every 3 bytes (24 bits) into 4 printable ASCII characters, which makes the output roughly 33% larger than the input. The standard alphabet uses + and /; the URL-safe variant (Base64URL, used in JWTs) swaps those for - and _. All encoding above runs in your browser — nothing is uploaded.
Base64 is encoding, not encryption (read this first)
This is the single most dangerous misconception about Base64. Encoding and encryption look similar — both turn readable text into unreadable-looking text — but they exist for opposite reasons.
- Encoding makes data safe to transportover channels that only accept text. There is no secret. The transformation is public and deterministic — anyone can reverse it instantly.
- Encryption makes data confidential. Without the key, reversing it is computationally infeasible. That key is the whole point.
Decoding cGFzc3dvcmQxMjM= back to password123 takes one function call and zero secrets. So:
- Never "Base64 a password" to protect it. HTTP Basic Auth sends
user:passas plain Base64 — which is exactly why it must only run over HTTPS. - The
payloadof a JWT is Base64URL, not encrypted. Anyone can read the claims inside it. The signature is what prevents tampering, not the encoding. - If a security tool flags Base64 in your code, it is often hunting for secrets that were "hidden" by encoding — a known anti-pattern, not a control.
Base64 vs Base64URL vs Base32: character sets compared
These three encodings are defined in RFC 4648. They differ in their alphabet, which positions are URL-safe, and how much they bloat the data. Pick the wrong one and a token silently breaks in a query string.
| Property | Base64 (standard) | Base64URL | Base32 |
|---|---|---|---|
| Alphabet size | 64 characters | 64 characters | 32 characters |
| Core characters | A–Z, a–z, 0–9 | A–Z, a–z, 0–9 | A–Z, 2–7 |
| Index 62 / 63 | + and / | - and _ | n/a (no 62/63) |
| Padding char | = | = (usually stripped) | = |
| URL / filename safe? | No (+ / = need escaping) | Yes (that's the point) | Yes (no special chars) |
| Case sensitive? | Yes | Yes | No (commonly uppercase) |
| Size overhead | ~33% larger (4 chars / 3 bytes) | ~33% larger | ~60% larger (8 chars / 5 bytes) |
| Best for | Email/MIME, data URIs, JSON blobs | JWTs, URLs, query params, filenames | Case-insensitive media: QR codes, voice, manual entry (TOTP secrets) |
Character sets and the padding rule are from RFC 4648 (Tables 1 and 2). Overhead percentages are derived from the encoding ratios shown and are approximate before padding.
Why Base64 grows your data by exactly one third
The 33% figure is not a rule of thumb — it falls directly out of the math. Base64 reads input in 3-byte chunks and emits 4 characters per chunk:
- 3 input bytes = 24 bits.
- 24 bits regrouped into 6-bit pieces = 4 pieces.
- Each 6-bit piece (value 0–63) maps to 1 character in the 64-character alphabet.
So 3 bytes become 4 bytes of output: a ratio of 4/3 ≈ 1.333, i.e. about 33% growth. Padding can add a little more: if the input length is not a multiple of 3, one or two = characters round the final block up to 4.
Input bytes: M (77) a (97) n (110) Binary: 01001101 01100001 01101110 Regroup (6-bit) 010011 010110 000101 101110 Index: 19 22 5 46 Base64 char: T W F u -> "TWFu" "Man" (3 bytes) -> "TWFu" (4 chars), no padding needed. "Ma" (2 bytes) -> "TWE=" (1 pad =) "M" (1 byte) -> "TQ==" (2 pad =)
Practical takeaway: a 1 MB image becomes roughly 1.33 MB as a Base64 data URI. That is the tradeoff for inlining it — you save an HTTP request but ship more bytes and lose the browser cache for that asset.
Where you actually meet Base64: data URIs and JWTs
Data URIs (inlining files in HTML/CSS)
A data URI embeds a whole file inside a URL. The structure is data:[<mediatype>][;base64],<data>. The MIME type and the ;base64 marker tell the browser how to decode it:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
^---- scheme ^----- payload (the Base64 of the PNG)
^mediatype ^encoding flagGood for tiny icons and SVGs. Avoid it for large images: the 33% bloat and the loss of caching usually outweigh the saved request.
JWT structure: header.payload.signature
A JSON Web Token is three Base64URL strings joined by dots. The first two are just encoded JSON — readable by anyone. Only the signature provides integrity:
eyJhbGciOiJIUzI1NiJ9 . eyJzdWIiOiIxMjMiLCJuYW1lIjoiQSJ9 . SflKxw...
\_____ header _____/ \_________ payload _________/ \_signature_/
(Base64URL JSON) (Base64URL JSON) (Base64URL bytes)
header decodes to: {"alg":"HS256"}
payload decodes to: {"sub":"123","name":"A"}Because the parts are Base64URL, JWTs notably have no = padding and no + or /. You can paste the header or payload segment into the decoder above to read the JSON — but never put a secret in a JWT payload, since it is not encrypted.
Base64 questions developers actually search
Is Base64 encryption? Is it secure?
No. Base64 is encoding, not encryption, and it provides zero security. There is no key — the transformation is public and any decoder reverses it instantly. Treat a Base64 string as plaintext. To protect data, encrypt it (for example AES) and then Base64-encode the ciphertext for transport if needed.
What is the difference between Base64 and Base64URL?
They share the same A–Z, a–z, 0–9 core. Standard Base64 uses + and / for indexes 62 and 63 and = for padding — all three are unsafe in URLs. Base64URL swaps them for - and _ and usually drops the padding, so the string survives query strings and filenames untouched. JWTs use Base64URL.
Why is my Base64 string about 33% bigger than the original?
Because Base64 emits 4 characters for every 3 input bytes (4/3 ≈ 1.333). Each output character carries only 6 bits of the original 8-bit byte, so you need more characters to represent the same data. Padding can add a byte or two on top when the input length is not a multiple of 3.
What are the = signs at the end of a Base64 string?
Padding. Base64 works in 4-character blocks. If the final block has only 2 or 3 characters of real data, it is padded with = to reach 4. One = means the last block encoded 2 bytes; two == means it encoded 1 byte. Base64URL strings often strip padding entirely, which is why JWT segments have none.
Why does my Base64 fail to decode with "invalid character"?
The usual cause is mixing variants: a Base64URL string (containing - or _) fed into a standard Base64 decoder, or vice versa. Other causes are missing or wrong padding, stray whitespace or newlines from copy-paste, or URL-encoded characters like %3D instead of =. Normalize the variant and padding first.
Can I decode a JWT here to read its contents?
Yes, for the header and payload. Split the token on the dots and paste either of the first two segments into the decoder above — they are Base64URL-encoded JSON. The third segment is the signature (raw signed bytes), so it will not decode to readable text. Decoding only reads a JWT; it cannot verify it, and you should never paste a live production token into any third-party site.
Disclaimer:This page is technical reference material, not security advice. Base64 provides no confidentiality. Do not rely on encoding to protect passwords, tokens, or personal data — use proper encryption and follow your organization's security policy. Character sets and padding rules described here follow RFC 4648; consult the spec for authoritative detail.