How Base64 Works
Base64 turns every 3 bytes into 4 characters, so the output is about 33% larger: "Man" becomes TWFu and "Hello, World!" becomes SGVsbG8sIFdvcmxkIQ==. This tool encodes text as UTF-8 first, so accents, symbols and emoji come out right. Paste text or drop a file to encode it, or switch to Decode to read a Base64 string.
- Type or paste text, or drop a file, in Encode mode. Text is turned into UTF-8 bytes first.
- Each group of 3 bytes (24 bits) is split into four 6-bit values from 0 to 63.
- Each value is looked up in the alphabet A to Z, a to z, 0 to 9, + and /.
- If the last group has only 1 or 2 bytes, the output is padded with == or =.
Switch to Decode to reverse it. Encoding and decoding run in your browser with JavaScript; the text and files you use are not uploaded.
Base64 Examples You Can Check
Type any of these into the tool to confirm the output. The last column is the URL-safe variant with padding removed, the form used in JWTs.
| Input | UTF-8 bytes | Standard Base64 | URL-safe, no padding |
|---|---|---|---|
| Man | 3 | TWFu | TWFu |
| Ma | 2 | TWE= | TWE |
| M | 1 | TQ== | TQ |
| Hello, World! | 13 | SGVsbG8sIFdvcmxkIQ== | SGVsbG8sIFdvcmxkIQ |
| user:pass | 9 | dXNlcjpwYXNz | dXNlcjpwYXNz |
| héllo | 6 | aMOpbGxv | aMOpbGxv |
| € | 3 | 4oKs | 4oKs |
| 😀 (emoji) | 4 | 8J+YgA== | 8J-YgA |
| Hi?> | 4 | SGk/Pg== | SGk_Pg |
Notice that "héllo" has 5 letters but 6 bytes: é takes two bytes in UTF-8. The emoji and "Hi?>" rows show where the URL-safe alphabet swaps + for - and / for _.
How Much Bigger Base64 Makes Data
The encoded length is 4 × (bytes ÷ 3, rounded up). Line breaks, if you turn on wrapping, come on top.
| Input size | Base64 characters | Growth |
|---|---|---|
| 1 byte | 4 | 4.00× |
| 3 bytes | 4 | 1.33× |
| 10 bytes | 16 | 1.60× |
| 100 bytes | 136 | 1.36× |
| 1,000 bytes | 1,336 | 1.34× |
| 1 MiB (1,048,576 bytes) | 1,398,104 | 1.33× |
Wrapped at 76 characters with CRLF line endings, as MIME email does, that 1 MiB file becomes 18,397 lines and 1,434,896 characters. This is why a 10 MB attachment can push an email past a 13 MB limit.
Why btoa() Fails on Unicode Text
The browser's btoa() only accepts characters with codes 0 to 255, so btoa('€') throws an InvalidCharacterError. Encode the text to UTF-8 bytes first:
- Browser:
btoa(String.fromCharCode(...new TextEncoder().encode(text)))for short strings. - Node.js:
Buffer.from(text, 'utf8').toString('base64'), and'base64url'for the URL-safe form. - Python:
base64.b64encode(text.encode('utf-8')).
The character set matters. "é" is w6k= in UTF-8, 6Q== in Latin-1 and 6QA= in UTF-16LE. All three are valid Base64, but only the first decodes to "é" in this tool and in most web APIs.
Common Errors and How to Fix Them
- "Invalid Base64 string": the input has characters outside the alphabet. A frequent cause is pasting a whole data URI; delete everything up to and including
base64,first. Spaces and line breaks are fine, the tool strips them. - Wrong length: after removing whitespace, a length that leaves a remainder of 1 when divided by 4 is never valid. Part of the string was cut off when it was copied.
- "Not UTF-8 text": the Base64 is fine but holds binary data, such as a PNG or a zip file. Decode it with a file tool instead of reading it as text.
- Encoded twice: if the output of a decode still looks like Base64, it was encoded twice. "Hello" once is
SGVsbG8=, twice isU0dWc2JHOD0=. Decode again. - Garbled accents such as é: UTF-8 bytes were read as Latin-1 somewhere along the way. Re-encode from the original text as UTF-8.
Base64 Explained
+, and /. It was invented to safely transmit binary data (images, files) through systems designed only for text, like email (MIME). Common uses today: embedding images directly in HTML/CSS as data URIs (data:image/png;base64,...), encoding binary attachments in emails, passing data through JSON APIs that only accept strings, HTTP Basic Authentication (Authorization: Basic dXNlcjpwYXNz), and storing binary data in databases. Base64 increases data size by about 33%.+ and / which have special meaning in URLs (+ means space, / separates path segments). URL-safe Base64 (RFC 4648 Section 5) replaces + with - and / with _, making the output safe to include directly in URLs and filenames without percent-encoding. The = padding characters can also be removed since the length is usually known in context. URL-safe Base64 is used in JWT (JSON Web Tokens), OAuth 2.0 PKCE, URL shorteners, file naming, and any context where the Base64 string appears in a URL. Toggle the URL-safe checkbox above to use this variant.SGVsbG8gV29ybGQ= decoded immediately to Hello World illustrates this clearly. Base64 only converts binary data to a text-safe format for transmission. For actual security, use encryption algorithms like AES-256 or RSA on top of Base64 if needed. Never use Base64 alone to "hide" or "protect" sensitive information like passwords, tokens, or personal data.= or == is added. Example: "Man" (0x4D 0x61 0x6E = 01001101 01100001 01101110) becomes four 6-bit groups: 010011 010110 000101 101110 = indices 19, 22, 5, 46 = "TWFu". This is why Base64 output is always about 4/3 (≈133%) the size of the input.data:[mediatype];base64,[data]. Example: <img src="data:image/png;base64,iVBOR...">. This eliminates an HTTP request for that resource. Use cases: embedding small icons, logos, or background images in CSS to reduce HTTP requests; embedding assets in email HTML where external URLs may be blocked; single-file HTML documents that include all assets. Avoid for large files: a 100KB image becomes ~133KB in Base64, and the browser cannot cache it separately. Best used for assets under 5 to 10KB. This tool generates the data URI automatically when you drop an image file.btoa(text) encodes a string to Base64, atob(base64) decodes it. Important: btoa() only handles Latin-1 characters. For Unicode/UTF-8 strings: btoa(unescape(encodeURIComponent(str))) to encode, and decodeURIComponent(escape(atob(b64))) to decode. In Node.js: Buffer.from(text).toString('base64') to encode, Buffer.from(b64, 'base64').toString('utf8') to decode. For URL-safe Base64 in Node.js, use base64url package or replace + with -, / with _, and remove = padding manually.= characters are appended to make the output length a multiple of 4. One = means 1 byte of padding; == means 2 bytes. The padding makes the length unambiguous for decoders. Padding can be safely omitted when the length is known from context: for example, in JWT tokens and URL-safe Base64, the = is typically stripped since the parser knows the total length. The "No padding" checkbox above removes the trailing = characters. Most modern decoders can handle unpadded Base64, but some strict implementations require padding.\r\n) line endings. This originated from limitations in early email software and telecommunications that could not handle very long lines. Modern systems generally do not require line wrapping, but it is still standard in PEM-encoded certificates and some email contexts. The "Line wrap" selector above lets you choose 64 characters (PGP/SSH standard), 76 characters (MIME email standard), 128 characters, or no wrapping. For most web and API uses, no wrapping is preferable.background-image: url('data:image/png;base64,iVBOR...');. Or in HTML: <img src="data:image/svg+xml;base64,PHN2Zy...">. For SVG files, you can often embed them without Base64 by URL-encoding the SVG text: url("data:image/svg+xml,%3Csvg..."). Base64 images increase HTML/CSS file size and disable browser caching for that asset separately, so use them only for very small images (icons under 1 to 2KB).echo 'SGVsbG8=' | base64 --decode, which prints Hello. To encode, use printf 'Hello' | base64; printf avoids the trailing newline that echo adds, which would change the output to SGVsbG8K. In PowerShell: [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('SGVsbG8=')). On Windows Command Prompt, certutil -decode in.txt out.bin decodes a file.