Base64 Encoder/Decoder

Encode text to Base64 or decode Base64 strings. Unicode supported.

Base64: how it works, where it appears, and why it is not encryption

Base64 (RFC 4648) turns arbitrary bytes into text that survives systems built for characters only: email, JSON, XML, URLs, config files. It takes each group of three bytes (24 bits), splits them into four 6-bit values, and maps each value to one of 64 characters: A-Z, a-z, 0-9, + and /. When the input is not a multiple of three bytes, the last group is filled out with one or two = padding characters. The text "Hi" (two bytes) becomes SGk=, and "Hi!" (three bytes) becomes SGkh. Every three bytes cost four characters, so encoded data is one third larger than the original, plus padding.

Two alphabets and two line lengths

Section 4 of RFC 4648 defines the standard alphabet above. Section 5 defines base64url, which swaps + for - and /for _ so the text can sit inside a URL or a filename without percent-encoding, and usually drops the padding; JSON Web Tokens use this form. Older standards also wrap lines: MIME email (RFC 2045) breaks encoded attachments every 76 characters and PEM certificates and keys (RFC 7468) every 64, which is why a certificate file is a block of short lines between -----BEGIN and -----ENDmarkers. Line breaks and spaces carry no data and decoders are expected to skip them.

What this tool does

Encode mode converts your text to UTF-8 bytes first and then to Base64, so Devanagari, Tamil, emoji and any other Unicode text round-trip correctly. (The browser's built-in btoa() cannot do this; see below.) Decode mode is deliberately lenient: it accepts the standard and the URL-safe alphabet, tolerates missing padding, and ignores spaces and line breaks, so you can paste a wrapped PEM body or a MIME part directly. The trade-off is that characters outside the alphabet are silently dropped rather than reported, and an input whose length cannot be decoded shows "Invalid Base64 string", so check the output rather than relying on an error. Decoded bytes are shown as UTF-8 text; if the bytes were an image, a PDF or a zip archive you will see unreadable characters, which is expected. Use the Image to Base64 tool for pictures or a command-line decoder that writes bytes to a file. The swap button feeds the output back into the input so you can round-trip a value in the other direction.

Where you meet Base64 every day

PlaceWhat is encodedDetail
HTTP Basic auth (RFC 7617)user:passwordAuthorization: Basic dXNlcjpwYXNz is just user:pass; TLS is what protects it, not Base64.
JSON Web TokensHeader and payload JSONbase64url without padding, three segments joined by dots.
data: URLs (RFC 2397)Images, fonts, small filesdata:image/png;base64,iVBORw0... embeds a file in HTML or CSS.
PEM filesDER-encoded certificates and keys64-character lines between BEGIN and END markers.
Kubernetes SecretsEvery value under data:Encoded, not encrypted. Anyone who can read the object can read the secret.
SSH public keysThe key blob after ssh-ed25519 or ssh-rsaThe AAAA... text is Base64 of the binary key structure.
Email (MIME)Attachments and non-ASCII bodiesContent-Transfer-Encoding: base64, wrapped at 76 characters.
SAML, Docker config, OAuth client secretsXML assertions, registry credentialsSame idea: binary or structured text made safe for a text field.

The btoa() trap

The browser functions btoa() and atob() operate on "binary strings" where every character must be a single byte (code points 0 to 255). Pass them a string containing ₹, an emoji or any Indian-language character and they throw InvalidCharacterError. The correct route is to encode to UTF-8 bytes first with TextEncoder, then Base64 the bytes. In Node.js the equivalent is Buffer.from(text, 'utf8').toString('base64') and Buffer.from(b64, 'base64').toString('utf8'), and Node also accepts 'base64url' as an encoding name.

Command-line equivalents

printf 'hello' | base64                       # GNU coreutils and macOS: aGVsbG8=
base64 -d <<< 'aGVsbG8='                      # decode (older macOS builds use -D)
base64 -w 0 file.bin > file.b64               # GNU: single line, no wrapping
openssl base64 -A -in file.bin                # -A: single line
python3 -c "import base64; print(base64.b64encode(b'hello').decode())"
node -e "console.log(Buffer.from('hello').toString('base64'))"
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes('hello'))            # PowerShell
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('aGVsbG8='))

Encoding, hashing and encryption are three different things

Base64 hides nothing

Base64 is reversible by anyone, with no key, in one line of code. It is not encryption, and it is not compression either (it makes data bigger). Never rely on it to protect passwords, API keys or tokens in a config file, a Kubernetes Secret or a URL. Encrypt first if confidentiality matters, then Base64 the ciphertext for transport.

An encoding (Base64, hex, percent-encoding) is a reversible representation. A hash (SHA-256, MD5) is a one-way fingerprint that cannot be reversed. Encryption (AES, RSA) is reversible only with a key. The Base64 versus encryption guideworks through examples of each. Two practical consequences: compress before you encode if size matters (gzip then Base64, never the reverse), and when a Base64 value must travel in a URL either use base64url or percent-encode the +, / and = characters.

How to use

  1. Choose Encode to turn text into Base64, or Decode to turn Base64 back into text.
  2. Paste or type in the input box. The output updates as you type; Unicode text is handled as UTF-8.
  3. When decoding, wrapped or URL-safe input is accepted as is. If the output looks like random symbols, the original was binary data rather than text.
  4. Use the swap button to move the output into the input and convert in the other direction, or Copy to take the result.

Common use cases

  • Reading the user name inside an Authorization: Basic header while debugging an API call.
  • Decoding a Kubernetes Secret value, or encoding one before writing a manifest by hand.
  • Embedding a small SVG icon or web font in CSS as a data: URL to avoid an extra request.
  • Inspecting a JWT segment or a SAML response that arrived as Base64 text.
  • Preparing binary payloads (a PDF, a signature) to travel inside a JSON field.
  • Checking why an email attachment or a MIME part was corrupted in transit.

Frequently asked questions

Is Base64 a form of encryption?

No. Base64 is a reversible encoding with no key; anyone can decode it instantly. It exists to carry binary data through text-only channels. If a value must stay confidential, encrypt it first and then Base64 the ciphertext.

Why do some Base64 strings end with one or two equals signs?

The equals signs are padding. Each group of four characters represents three bytes, so an input whose length is not a multiple of three leaves the last group short: one leftover byte produces two equals signs, two leftover bytes produce one. Many decoders, including this one, also accept the string without padding.

What is URL-safe Base64 (base64url)?

A variant defined in RFC 4648 section 5 that replaces + with - and / with _ so the result can appear in URLs, filenames and cookies without escaping, and that normally omits padding. JWTs use it. This tool decodes both alphabets.

Why is my decoded output a mess of strange characters?

Usually because the original data was binary (an image, a certificate in DER form, a zip) rather than text, so rendering it as UTF-8 produces noise. It can also mean the value was Base64-encoded twice, in which case decode the output once more, or that it is actually hex or another encoding.

How much bigger does Base64 make my data?

Exactly four output characters for every three input bytes, so about 33 percent larger, plus up to two padding characters and any line breaks. A 750 KB image becomes about 1 MB as a data URL, which is why inlining is only worthwhile for small assets.

Why does btoa() throw InvalidCharacterError on my text?

btoa() only accepts characters with code points 0 to 255. Any character outside that range, including the rupee sign, emoji and all Indian scripts, causes the error. Convert the string to UTF-8 bytes with TextEncoder first, or use Buffer.from(text).toString('base64') in Node.

Are Kubernetes Secrets safe because they are Base64?

No. Base64 in a Secret manifest only avoids problems with binary values and special characters. Anyone with read access to the object, or to a Git repository where the manifest is committed, can decode every value. Use encryption at rest, RBAC and a secrets manager for real protection.

Can I encode a file or an image here?

This page works with text. For images use the Image to Base64 tool, which reads the file in your browser and produces a data URL. For other files use the command line, for example base64 -w 0 file.bin on Linux.

Advertisement