Free online Base64 encoder
Base64 encode in the flavour your target reads
Type text or drop a file and the Base64 builds as you go, free and without an account. Everything is converted to UTF-8 bytes first, so ß, 東京 and an emoji come back out of a decoder exactly as you wrote them, and four controls cover the variants that actually differ in the wild: the standard + / alphabet or the URL-safe - _ one, = padding kept or dropped, lines wrapped at 64 columns for PEM or 76 for MIME, and a data: URI with the media type already in front of it. Files run to 5 MB, which turns into 6,990,508 characters in about a fifth of a second.
- 100% free
- No signup
- Files up to 5 MB
- Standard or URL-safe
- PEM and MIME wrapping
The encoded string appears here as you type.
Nothing to encode yet. Type, drop a file, or press Ctrl+V anywhere on this page.
How to encode text or a file as Base64
Three steps: put something in, choose the variant, take the string.
Type, paste or drop
Write into the left box, paste from the keyboard without clicking in first (⌘V, or Ctrl+V off a Mac) to pull text or a file straight off the clipboard, or drag a file onto the panel. Text is measured in UTF-8 bytes as you go — the counter above the box shows the byte total, which is what the encoder actually works from, not the number of characters you typed.
Match the variant to the consumer
Four switches cover every common flavour: standard + / against URL-safe - _, = padding on or off, one long line against 64 columns for PEM or 76 for MIME, and LF against CRLF for those wrapped lines. Turning on data: URI locks wrapping off and prefixes the string with the media type, guessed from the file or from what the text looks like.
Copy it, or save it beside the source
Copy takes the whole string even when the pane stops drawing at 60,000 characters. Download writes a .b64 file named after the source, so photo.png leaves as photo.png.b64 and stays next to the original. The line under the tool keeps the receipts: bytes in, characters out, the growth as a percentage, how many of those characters are padding, and how many lines the wrapping produced.
Technical specifications
| Accepted input | Typed or pasted text of any script, and any file up to 5 MB (5,242,880 bytes) — images, fonts, PDFs and archives included, read as bytes rather than as text |
|---|---|
| Text handling | Converted with TextEncoder to UTF-8 before encoding, so ß, 東京 and emoji round-trip; btoa alone throws on anything above U+00FF |
| Alphabets and padding | Standard RFC 4648 §4 (+ and /) or URL-safe §5 (- and _), with = padding on or off; unpadded base64url is what RFC 7515 requires of a JWT and what most URL-safe APIs expect. Both switch instantly, without re-reading the file |
| Line wrapping | One line, 64 columns (PEM, RFC 7468) or 76 columns (MIME, RFC 2045), with LF or CRLF endings |
| Measured output | 4 characters per 3 bytes exactly: 5,242,880 bytes produce 6,990,508 characters in about 0.2 seconds, or 91,981 lines when wrapped at 76 |
| data: URI | data:<type>;base64,<payload> with the type taken from the file, from its extension, or inferred as application/json, image/svg+xml or text/plain;charset=utf-8 for typed text |
| Output handling | Copy carries the full string past the 60,000-character preview cap; Download writes <original-name>.b64 for a file, encoded.b64.txt for typed text, data-uri.txt in data: URI mode |
| Price and processing | Free for any number of files, with no registration; the encoding happens inside this browser tab and no bytes leave it |
Frequently asked questions
Why is the Base64 a third bigger than the file I encoded?
Because Base64 spends 8 bits of output on every 6 bits of input: it slices the data into 6-bit pieces so that each piece can be one of 64 printable characters, and every group of 3 bytes leaves as 4 characters. That is a fixed 4/3 ratio, or +33.33%, before anything else — a 5 MB file becomes exactly 6,990,508 characters. Padding adds up to 2 characters, line wrapping at 76 columns adds another 91,981 line breaks to that same file, and a data: URI prefix adds the length of the media type on top. The overhead is the price of moving bytes through a channel that only promises to carry text.
Standard or URL-safe — which alphabet do I need?
Use URL-safe when the string will sit in a URL, a filename or a cookie, and standard everywhere else. The two differ in exactly two characters out of 64: RFC 4648 §4 ends its table with + and /, while §5 substitutes - and _ for them. Those two are the ones that break in transit — + is decoded as a space by form parsers, and / cuts a value in half when it lands in a path segment. Both alphabets decode back to identical bytes, so the choice is about the channel, never about the data.
Should I turn the = padding off?
Turn it off when the consumer is a JWT, a URL or anything that would have to percent-encode the = as %3D. RFC 7515, which defines the JSON Web Signature format, requires base64url with the padding omitted, and most modern web APIs follow it. Keep the padding for MIME, for PEM and for older libraries, some of which raise an error on an unpadded string rather than working the length out for themselves. The padding carries no data either way: it only rounds the last group up to four characters.
Why does one emoji turn into 8 characters?
Because it is 4 bytes before it is anything else. Base64 encodes bytes, not letters, so text is converted to UTF-8 first: 😀 is F0 9F 98 80, four bytes, which fill one full group of 4 characters and start a second, giving 8J+YgA== — 8 characters. The same arithmetic explains the rest of Unicode: café is 5 bytes and comes out as Y2Fmw6k=, 東京 is 6 bytes and comes out as 5LiW55WM with no padding at all. Anything that encodes text through the browser's raw btoa() instead throws on those inputs, because btoa refuses any character above U+00FF.
Do I need to wrap the lines at 76 characters?
Only when a MIME parser is on the other end. RFC 2045 caps an encoded body at 76 characters per line and expects CRLF endings, which is why mail attachments look the way they do; PEM, defined by RFC 7468, uses 64 instead and wraps its payload in BEGIN and END lines. HTTP headers, JSON fields, database columns and data: URIs all want one unbroken line, and a stray newline inside a data: URI truncates it as far as the CSS or HTML parser is concerned. That is why switching this page to data: URI output turns wrapping off and keeps it off.
How do I make a data: URI for CSS or an img tag?
Encode the file, tick “data: URI”, and paste the result where a URL would go. The output takes the form data:image/svg+xml;base64,PHN2Zy… — the media type comes from the file the browser reported, from its extension when the browser says nothing, and from the shape of the text when you typed it in. Inlining is a real trade for small assets: it removes a request but adds 33% to the bytes and the asset can no longer be cached on its own, so icons and 1 KB SVGs usually win while photographs do not.
Why does my terminal produce a different string from this page?
Nine times out of ten because the shell added a newline your text did not have. echo "hello" | base64 gives aGVsbG8K, where the trailing K is the encoded 0A; printf 'hello' | base64 gives aGVsbG8= instead. The other cause is wrapping: GNU coreutils breaks its output at 76 columns unless you pass -w 0, macOS's base64 emits one line unless you pass -b 76, and openssl base64 wraps at 64. Same bytes, different presentation — decode both and they agree.
About encoding to Base64
Base64 exists because a great deal of infrastructure was built to carry text and only text. Early mail servers stripped the eighth bit off every byte, protocols reserved control codes for their own use, and anything that looked like a line ending was liable to be rewritten in transit. The answer, standardised in RFC 4648 after a decade of MIME practice, was to choose 64 characters that survive that journey unharmed — A–Z, a–z, 0–9 and two more — and to re-express arbitrary bytes in them. Encoding walks the input in groups of 3 bytes, splits each 24-bit group into four 6-bit numbers, and looks each number up in that table. Nothing is compressed, nothing is hidden, and nothing about the original file is recorded: the same 4 characters come out whether those 3 bytes were part of a sentence or part of a JPEG.
The cost is exact and worth budgeting for. Four characters per three bytes is a 33.33% increase, so inlining a 40 KB font as a data: URI puts 53 KB into the stylesheet, and that stylesheet can no longer be cached separately from the font it now contains. For a 16×16 icon or a small SVG the trade is usually good: one request saved, no extra connection, no flash of a missing image. For photographs it rarely is, and a picture converted to a data: URI should be checked against what it costs on a slow connection before it ships. The same arithmetic is why an API that returns a document as a Base64 field always transfers noticeably more than the document weighs.
Which variant to emit is the part people get wrong, and it is entirely a question of who reads the string next. A JWT signature is base64url with no padding, because RFC 7515 says so and because = would have to be written %3D in a query string. A PEM certificate is standard Base64 at 64 columns between BEGIN and END markers. A MIME attachment is standard Base64 at 76 columns with CRLF endings. A data: URI is standard Base64 on one unbroken line. All four decode to the same bytes, so a string that a strict parser rejects is almost never corrupt — it is the right data in the wrong dress, and running it back through the decoder is the quickest way to prove it.
What happens to a file you drop here
It is read by the browser and encoded in this tab — there is no upload step, no temporary copy on a server and no request that carries your bytes anywhere. The file object hands its contents straight to JavaScript running on your own machine, which is why a 5 MB file encodes just as fast with the network disconnected.