
You've probably seen strings like SGVsbG8sIFdvcmxkIQ== and thought: "This looks encrypted." You paste it into a decoder, click a button, and out comes Hello, World! — no key, no secret. That's because Base64 is not encryption. It's a binary-to-text encoding scheme, and confusing the two can lead to serious security holes.
This article clears up that misconception, explains what Base64 actually does, how it works under the hood, and when to reach for Base64 vs hex (hexadecimal). We'll also walk through a complete end-to-end example so you can see it in action.
Encoding vs Encryption: Two Very Different Things
Let's get this straight from the start:
| Property | Encoding (e.g., Base64, hex) | Encryption (e.g., AES, RSA) |
|---|---|---|
| Purpose | Represent binary data as text for safe transport | Protect data from unauthorized access |
| Key required? | No | Yes |
| Reversible without secret? | Yes, anyone can decode | No, requires the key |
| Example | Man → Base64 → TWFu → decode → Man |
Man → AES → 0x3a7f... → decrypt(key) → Man |
Think of encoding as translating a book into English: anyone who knows English can read it. Encryption is locking that book in a safe: without the key, nobody can read it.
Common pitfall: Developers sometimes Base64-encode ciphertext and think it's "more secure." This is like putting a safe's combination on the door — the safe itself is secure, but you've just undone that security.
Why Do We Need Binary-to-Text Encoding?
Computers store everything as bytes (0x00–0xFF). Many of those bytes are non-printable — they don't have a visible character. For example:
0x00(NULL) — many systems treat this as end-of-string0x0A(newline) — email servers may break lines0x0D(carriage return) — causes issues across OSes
If you try to shove raw binary into a text-only channel like email, URL, or JSON, you'll get corruption, truncation, or parse errors. Binary-to-text encoding solves this by mapping arbitrary bytes to a set of safe, printable characters.

How Base64 Works: The 3-Byte to 4-Character Magic
The Encoding Table
Base64 uses 64 printable ASCII characters:
A–Z(indices 0–25)a–z(indices 26–51)0–9(indices 52–61)+(index 62) and/(index 63)=for padding
Why these 64? They're safe across all systems — no control characters, no special meaning in most protocols.
The Encoding Process
- Take 3 bytes (24 bits) of input.
- Split those 24 bits into 4 groups of 6 bits each.
- Map each 6-bit value (0–63) to a character in the table.
Let's encode Man:
Input bytes: M a n
ASCII: 77 97 110
Binary: 01001101 01100001 01101110
24-bit stream: 010011010110000101101110
6-bit groups: 010011 010110 000101 101110
Decimal: 19 22 5 46
Table char: T W F u
Result: "Man" → "TWFu"
3 bytes become 4 characters. The math: 3 × 8 = 24 bits; 24 / 6 = 4 characters.
Padding: When Data Isn't a Multiple of 3
If the input length isn't a multiple of 3, we pad with zero bits and mark the padding with =:
- 1 byte (8 bits): pad to 24 bits, encode → 2 chars +
==(e.g.,A→QQ==) - 2 bytes (16 bits): pad to 24 bits, encode → 3 chars +
=(e.g.,AB→QUI=) - 3 bytes (24 bits): no padding (e.g.,
ABC→QUJD)
Size Overhead
Base64 adds about 33% overhead: ceil(N/3) × 4 characters for N input bytes. Hex (hexadecimal) doubles the size (each byte becomes 2 hex characters), so Base64 is more compact.
Base64 vs Hex: When to Use Which?
| Feature | Base64 | Hex |
|---|---|---|
| Characters used | 64 (A–Z, a–z, 0–9, +, /) | 16 (0–9, A–F) |
| Overhead | ~33% | 100% (2×) |
| Human-readable? | Not really | Somewhat (hex digits are familiar) |
| Common uses | Email attachments, data URIs, API payloads | Memory dumps, color codes, debugging |
When to use Base64:
- Embedding binary data in JSON/XML
- Sending binary in email (MIME)
- Data URIs for small images in HTML/CSS
- Storing binary in text-only databases
When to use hex:
- Debugging and logging (easier to eyeball)
- Representing hash digests (e.g., SHA-256)
- Low-level protocols where size isn't critical
Worked Example: Encoding and Decoding a File
Let's take a real-world scenario: you have a small image file (32 bytes) that you want to embed in a JSON API response. You'll encode it as Base64.
Step 1: Get the raw bytes
We'll use a minimal 32-byte PNG header (not a real image, just raw bytes):
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
00 00 00 01 00 00 00 01 08 02 00 00 00 90 77 53
Step 2: Encode with Python
import base64
raw_bytes = bytes([
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53
])
encoded = base64.b64encode(raw_bytes).decode('ascii')
print(encoded)
# Output: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1VT
Step 3: Decode back
decoded_bytes = base64.b64decode(encoded)
assert decoded_bytes == raw_bytes # True
You can verify this with our Base64 String Converter — paste the encoded string and see the decoded hex.
Common Pitfalls
- Thinking Base64 is encryption: It's not. Anyone can decode it with a simple tool. Never use it to protect sensitive data.
- Double-encoding: Encoding already encoded data (e.g., Base64 of a Base64 string) wastes space and adds no security.
- Padding errors: Missing or extra
=characters cause decode failures. Always handle padding correctly. - URL safety: Standard Base64 uses
+and/, which have special meaning in URLs. Use Base64url (replace+with-,/with_, omit padding) for URLs. - Performance: Base64 encoding/decoding is fast, but for large files (MBs), the 33% overhead can be significant. Consider streaming or compression.
FAQ
Is Base64 secure for passwords?
No. Base64 is encoding, not hashing or encryption. Passwords should be hashed with a slow, salted algorithm like bcrypt or Argon2.
Can Base64 be used for encryption if I keep the table secret?
Security through obscurity is not security. The Base64 algorithm is public and trivial to reverse. Anyone who sees the encoded string can decode it, even if you use a custom character set.
Why does Base64 use padding (=)?
Padding ensures that the encoded output length is always a multiple of 4 characters. Some decoders can handle missing padding, but it's not guaranteed.
What's the difference between Base64 and Base64url?
Base64url uses - and _ instead of + and /, and omits padding. It's safe for use in URLs and filenames without percent-encoding.
How do I convert Base64 to hex?
Decode the Base64 string to bytes, then encode those bytes as hex. For example, in Python: base64.b64decode(s).hex(). Our Base64 String Converter can show both representations.
Conclusion
Base64 is a useful tool for transmitting binary data over text-only channels, but it is not encryption. Understanding the difference between encoding and encryption is crucial for building secure systems. When you need confidentiality, use a proper encryption algorithm with a secret key. When you just need to move bytes around safely, Base64 (or hex) is your friend.
Remember: if you can decode it without a key, it's not encryption.