StringToolsStringTools

Base64 Encode / Decode

Encode text to Base64 or decode Base64 strings back to plaintext. Supports full UTF-8 characters.

Mitul MandankaFounder, Progragon Technolabs · 15+ years building software
Updated June 20267 min read
Input0 chars
Output
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:pass as plain Base64 — which is exactly why it must only run over HTTPS.
  • The payload of 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.

PropertyBase64 (standard)Base64URLBase32
Alphabet size64 characters64 characters32 characters
Core charactersA–Z, a–z, 0–9A–Z, a–z, 0–9A–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?YesYesNo (commonly uppercase)
Size overhead~33% larger (4 chars / 3 bytes)~33% larger~60% larger (8 chars / 5 bytes)
Best forEmail/MIME, data URIs, JSON blobsJWTs, URLs, query params, filenamesCase-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 flag

Good 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.