What is Base64?
Base64 is a binary-to-text encoding scheme that represents binary data as a string of 64 printable ASCII characters. It is not encryption, not compression, and not a security measure. It is a way to safely transport binary data through systems that were designed to handle only text.
The 64-character alphabet consists of A-Z (26), a-z (26), 0-9 (10), and two symbols: + and /. The = character is used for padding but is not part of the core alphabet.
The name "Base64" comes from the fact that each character represents exactly 6 bits (2^6 = 64 possible values), which is more efficient than representing each byte as decimal or hexadecimal.
Why Base64 exists
Many protocols and file formats were designed in the era of 7-bit ASCII text. SMTP (email), HTTP headers, and XML all fall into this category. Sending raw binary through these systems can corrupt data: certain byte values have special meaning (control characters, line endings) and may be altered in transit.
Base64 solves this by mapping every possible byte value to a safe printable character. The encoded output contains no special characters that could confuse a text-based protocol. The trade-off is size: encoded output is always about 33% larger than the original binary.
How the algorithm works: encoding "Man"
Base64 processes input in groups of 3 bytes (24 bits) and produces 4 output characters (6 bits each). Here is a step-by-step trace of encoding the string "Man":
| Step | Value | Note |
|---|---|---|
| 1. ASCII bytes | 77 97 110 | M=77, a=97, n=110 |
| 2. Binary (8-bit each) | 01001101 01100001 01101110 | 3 bytes = 24 bits |
| 3. Split into 6-bit groups | 010011 010110 000101 101110 | 4 groups of 6 bits |
| 4. Decimal values | 19 22 5 46 | Each 0-63 |
| 5. Base64 characters | T W F u | Lookup in alphabet table |
So Man encodes to TWFu. If the input had been only 2 bytes ("Ma"), the output would be TWE= with one padding character. One byte ("M") would produce TQ==.
Base64URL: the URL-safe variant
Standard Base64 uses + and /, which are special characters in URLs (+ means space in query strings; / separates path segments). Placing standard Base64 in a URL requires percent-encoding, which is messy.
Base64URL fixes this by replacing + with - and / with _. It also typically omits trailing = padding.
JWTs use Base64URL for both the header and payload. This is why JWT segments contain hyphens and underscores but never plus signs or forward slashes.
When to use Base64
Data URIs
Embed images and fonts directly in HTML or CSS without a separate HTTP request.
src="data:image/png;base64,iVBORw..."JWT structure
The header and payload of every JSON Web Token are Base64URL-encoded, not encrypted.
eyJhbGciOiJIUzI1NiJ9...HTTP Basic Auth
The Authorization header encodes username:password as Base64. This is why HTTPS is required.
Authorization: Basic dXNlcjpwYXNzEmbedding binary in JSON or XML
JSON has no binary type. Base64 lets you include file contents or raw bytes in a text payload.
{"file": "SGVsbG8gV29ybGQ="}Email attachments (MIME)
SMTP was designed for 7-bit ASCII. Base64 encodes binary attachments so they survive email transport.
Content-Transfer-Encoding: base64When NOT to use Base64
Storing passwords
Base64 is instantly reversible. Anyone with the encoded value has the plaintext. Use bcrypt, Argon2, or scrypt.
Securing or hiding data
Base64 is not encryption. It provides zero confidentiality. A simple atob() call decodes it in any browser.
Compressing data
Base64 makes data larger, not smaller. It increases size by approximately 33%.
Transmitting large files
The 33% size overhead is significant for large payloads. Use binary transports or multipart uploads instead.
Frequently asked questions
Is Base64 secure?
No. Base64 is an encoding scheme, not an encryption algorithm. Anyone who sees a Base64-encoded string can decode it immediately with a single function call. It provides no confidentiality, no integrity protection, and no authentication. If you need to protect data, use encryption (AES-256) or hashing (bcrypt for passwords).
Why does Base64 output end with == ?
Base64 processes input in groups of 3 bytes. If the input length is not a multiple of 3, the last group is padded with = characters to maintain the 4-character output block structure. One = means one byte of padding was added; == means two bytes of padding. Some implementations omit padding (Base64URL commonly does this).
What is a data URI?
A data URI is a URL scheme that embeds file contents directly in the URL itself, using Base64 encoding. The format is: data:[media type];base64,[encoded data]. For example, a small PNG can be included in an img src attribute without any network request. Useful for tiny images and icons; not recommended for large files because the browser cannot cache the data separately.
What is the difference between Base64 and Base64URL?
Standard Base64 uses + and / in its alphabet, which are special characters in URLs. Base64URL replaces + with - and / with _ to make the output safe for URLs, filenames, and HTTP headers without percent-encoding. Base64URL also typically omits the trailing = padding. JWTs use Base64URL for exactly this reason.
How do I encode and decode Base64 in JavaScript?
In browsers and Node.js (v16+): btoa(str) encodes a string to Base64 and atob(b64) decodes it. For binary data or files in Node.js, use Buffer.from(data).toString("base64") to encode and Buffer.from(b64str, "base64") to decode. Note that btoa only handles Latin-1 characters; for Unicode strings, convert to UTF-8 bytes first.