Base64 Encoder_
Turn text or any file into Base64: type and the encoding appears live, or choose a file and get its bytes encoded without an upload — for images, complete with a ready-to-paste data URI and a preview rendered from it. Standard or URL-safe alphabet, padding on or off, optional 76-column wrapping, and a size readout that shows the one-third growth before it surprises you.
What people encode is exactly what shouldn't travel: private keys, credentials, config secrets. The market-leading encoder submits your input to its server by default. This one cannot — encoding runs in this tab, enforced by policy and asserted by tests.
The file reports no MIME type — the data URI uses application/octet-stream.
—
- Input
- Typed or pasted text in any script, or a file picked from disk — an image, a PDF, a certificate. Emoji and non-Latin characters go through UTF-8 first, which is why they cost more than one byte each.
- Output
- A Base64 string in the alphabet your destination expects, padded or not, optionally wrapped at 76 characters or wrapped up as a
data:URI ready to paste into CSS or an<img>tag. - Processing
- Encoded here, including files: bytes are read through the File API in 24 KB blocks aligned to three, so a multi-megabyte upload never freezes the tab and never leaves it.
- Limits
- No file-size quota beyond your own memory. What does grow is the result — every three bytes in become four characters out, so budget about a third more than you started with.
- Pick the alphabet first
- A URL, a JSON body, an email header and a CSS rule each accept a different combination of alphabet, padding and line wrapping. Choosing before you copy saves the round trip of finding out downstream.
Base64 encoding, explained by doing it
What Base64 encoding actually is
Press encode and your input stops being bytes: it is re-spelled into A–Z, a–z, 0–9 and two symbols, three bytes at a time, four characters at a time. Whatever you started with — a sentence, a PNG, a private key — comes out as something you can paste anywhere a plain string is allowed. The cost is fixed and it is paid immediately: the result is about a third longer than the input, and when your bytes do not divide by three the last block is topped up with = so the length always lands on a multiple of four. This page is the encode half of a pair — the Base64 decoder reverses any output produced here, whatever alphabet and padding options you chose, because both pages share one engine.
Encoding an image — and when a data URI earns its keep
The most common file people encode is an image, and the usual goal is a data URI: data:image/png;base64,… pasted straight into a src attribute or a CSS url(). The File tab builds it for you with the correct MIME type read from the file, and renders the preview from the URI itself, so what you see is proof the string works. Use data URIs for small assets — icons under a few kilobytes, one-off email images — where saving a network request beats the cost. Skip them for anything sizable: the payload is a third bigger than the file, it can't be cached separately, and it re-downloads with every stylesheet or page that embeds it.
Standard vs URL-safe, and the padding question
The standard alphabet ends in + and / — both of which mean something else inside a URL, which is why RFC 4648 defines a second alphabet swapping them for - and _. JWTs, URL tokens, and filename-safe contexts use the URL-safe form, almost always with padding stripped as well; data URIs, MIME, and Basic auth use the standard form with padding intact. The two toggles here are independent because the wild contains every combination — and the context table below says which pair each destination expects. When a decoder rejects your output, alphabet mismatch is the first suspect: a strict standard-only decoder treats - and _ as garbage characters.
The same encode in JavaScript, Python, and a terminal
JavaScript's btoa() is the classic answer with a classic trap: it only accepts Latin-1, so btoa("café") throws or mangles. The modern pattern is bytes-first — btoa(String.fromCharCode(...new TextEncoder().encode(s))) in the browser, or simply Buffer.from(s).toString("base64") in Node (add "base64url" for the URL-safe alphabet). Python: base64.b64encode(s.encode()), with urlsafe_b64encode for the other alphabet. At a shell: base64 file.bin (GNU wraps at 76 by default; -w0 disables) or openssl base64 -in file.bin. Every one of them produces output this page's decoder — and any other — reads back identically.
Choose what to encode, then where it has to fit
- 01Type in the Text tab, or switch to File and choose anything on disk — the File API hands this page the bytes directly, so nothing is uploaded anywhere.
- 02Set the alphabet and padding for your destination: Standard with padding for data URIs, MIME, and Basic auth; URL-safe without padding for JWT-style and URL contexts. The table below the tool maps the common destinations.
- 03Turn on Wrap at 76 only when the consumer expects MIME-style line breaks — wrapped output breaks single-line contexts like headers and JSON strings.
- 04Copy or Download the result; for images, the Data_URI block has its own copy button and a preview rendered from the exact string you are about to paste.
Four encodings that come up constantly
A Basic auth header
HTTP Basic authentication is user:password encoded with the standard alphabet, padding kept.
deploy-bot:s3cr3t!
ZGVwbG95LWJvdDpzM2NyM3Qh
An icon inlined into CSS
A 400-byte SVG icon as a data URI saves a request; the preview proves the string renders before you paste it.
chevron.svg (412 B, image/svg+xml)
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxu…")Binary payload in a JSON field
JSON can't carry raw bytes; Base64 is the convention — one unwrapped line, standard alphabet.
report.pdf (48.2 KB)
{"filename":"report.pdf",
"content":"JVBERi0xLjcK…"}A Kubernetes secret, encoded locally
Secret manifests want Base64 values — precisely the input that must never touch a third-party server.
postgres://user:pass@db:5432/app
cG9zdGdyZXM6Ly91c2VyOnBhc3NAZGI6NTQzMi9hcHA=
What encoding costs you, and where that bill lands
| Input | Output characters | Padding | Growth |
|---|---|---|---|
| Formula: n bytes | 4 × ⌈n / 3⌉ | n mod 3 = 0 → none · 1 → == · 2 → = | ≈ +33% |
| 10 bytes | 16 chars | == | +60% (small inputs round up hard) |
| 1 KB (1,024 B) | 1,368 chars | == | +33.6% |
| 100 KB | 136,536 chars | depends on n mod 3 | +33.3% |
| 1 MB | ≈ 1.40 MB of text | — | +33.3% |
| 5 MB photo | ≈ 6.67 MB of text | — | +33.3% — why large data URIs hurt |
The growth is structural: 3 bytes of input always become 4 characters of output. Wrapping adds one newline per 76 characters on top — about 1.3% more.
Which options each destination expects
| Destination | Alphabet | Padding | Wrapping |
|---|---|---|---|
| Data URI (img src, CSS url) | Standard | Keep | Never |
| JWT segment | URL-safe | Strip | Never |
| HTTP Basic auth header | Standard | Keep | Never — headers are one line |
| MIME email attachment | Standard | Keep | Required (76 cols, CRLF in strict MIME) |
| JSON string field | Standard | Keep | Never — a raw newline breaks the string |
| URL query parameter | URL-safe | Strip (or %-encode the =) | Never |
Six destinations, three different option pairs — the reason this page has toggles instead of one hard-coded behavior.
Encoding for email, JSON, URLs and CSS
- Check the size strip before embedding: an output a third bigger than the file is correct, not a bug — budget for it in payload limits.
- Keep data URIs for assets under a few KB; beyond that, a real file request with caching wins on every metric except request count.
- Encoding secrets for Kubernetes or CI? Do it here or in your terminal — never in a tool whose default flow posts to a server.
- When a consumer rejects your output, compare alphabets first: one - or _ in standard-only input fails the whole string.
- For JSON payloads, leave wrapping off — a literal newline inside a JSON string is invalid, and 76-column wrapping inserts dozens.
- The GNU base64 command wraps at 76 by default; pipe with -w0 when the consumer wants one line, or your shell output and this page will disagree by newlines only.
Where an encoded string breaks the thing downstream
Encoding buys you transport, not protection
The button you just pressed changed the spelling and nothing else. It bought no secrecy — the result is reversible by anyone, in one call, with no key involved — and no space either, since the output is a third larger than what went in. If you are encoding a secret to put it somewhere safer, encode it and then encrypt it, because this step alone leaves it as readable as it was.
Data URIs trade caching for inlining
An inlined image re-downloads with every copy of the HTML or CSS that contains it, bloats the document a third beyond the original file, and cannot be cached or lazy-loaded on its own. The break-even is small: icons yes, photos no.
URL-safe output fails strict standard decoders
The two alphabets are one substitution apart, but a decoder expecting only + and / rejects - and _ outright. Match the alphabet to the consumer — and when you receive mystery Base64, try both before declaring it corrupt.
Wrapping is mandatory in some places and fatal in others
Classic MIME requires lines of at most 76 characters; JSON strings, HTTP headers, and data URIs tolerate no newlines at all. The same output can be valid in one context and syntactically broken in the other purely by line breaks.
Server-side encoders see everything you encode
TLS keys, htpasswd lines, kubeconfig blobs, ID scans — encoding jobs are disproportionately secrets. The most-trafficked encoder sites process input server-side unless you opt into their in-browser mode. Encoding here is a few lines of arithmetic over bytes you already have, so there is nothing for this page to send and nothing it is able to send.
What the encoder emits, and what it accepts
- File handling
- Uploads are read inside the page with the browser File API and are never transmitted; Download writes out what is already in the tab.
- Text encoding
- UTF-8 via TextEncoder, then RFC 4648 Base64 — emoji and non-Latin text produce correct multi-byte sequences (the btoa Latin-1 trap does not apply here)
- File encoding
- File API bytes, chunked in 24 KB blocks aligned to 3 bytes so multi-megabyte files encode without freezing the tab or emitting padding mid-stream
- Alphabets
- Standard (+ /) and URL-safe (- _), with padding as an independent toggle — every combination round-trips through the Base64 decoder page
- Wrapping
- Optional newline every 76 characters for MIME-style transport; strict MIME wants CRLF, noted where it matters
- Data URIs
- Built from the file’s reported MIME type (application/octet-stream fallback), always standard alphabet with padding — anything else breaks consumers
- Size readout
- Input bytes, output characters, and growth percentage — 4 × ⌈n/3⌉, about one third
- Limits
- The on-screen output stops drawing after 300k characters, which keeps a huge paste from stalling the tab. Copy and Download are unaffected and always carry the complete result.
- Processing
- Encoding, file reads, previews, and downloads all happen in this tab — input and files are never transmitted
Questions about making Base64 strings
What is Base64 encoding?
A way to hand any bytes to something that only accepts text: 64 safe characters standing in for the raw values, so a payload survives JSON, an HTTP header or an email body — JSON, HTTP headers, email, XML. Three bytes become four characters; = pads the final block. It is a transport format, not protection: anyone can reverse it instantly.
How do I Base64-encode an image?
Switch to the File tab and choose the image — you get the raw Base64 and a complete data URI with the right MIME type, plus a preview rendered from that exact URI. Paste it into an img src or CSS url(). Reserve the technique for small images; large ones are better served as real files the browser can cache.
How do I Base64-encode in JavaScript or Python?
Node: Buffer.from(text).toString("base64") — or "base64url" for the URL-safe alphabet. Browser: btoa handles only Latin-1, so encode UTF-8 first via TextEncoder. Python: base64.b64encode(text.encode()) and urlsafe_b64encode for the other alphabet.
Why is my encoded output bigger than the input?
By design: every 3 input bytes cost 4 output characters, a fixed +33% before wrapping. Base64 never compresses. If size matters, compress first (gzip, then encode) or transmit binary directly where the channel allows it.
Is Base64 encoding secure?
No — it hides nothing and requires no key to undo. Treat Base64-encoded credentials exactly like plaintext credentials: an Authorization: Basic header, for instance, is readable by anything that sees the request. For secrecy you need actual encryption; for integrity, a signature.
When do I need the URL-safe alphabet?
Whenever the output lives in a URL, filename, or JWT: + means space in query strings and / breaks paths, so RFC 4648 swaps them for - and _. Pair it with stripped padding in those contexts, since = has its own meaning in query strings.