The base64 module in the Python standard library encodes binary data into ASCII text and decodes it back. Base64 is used whenever binary data needs to travel through text-only channels: embedding images in HTML or CSS, attaching files to JSON payloads, storing binary data in text-based databases, and encoding credentials in HTTP headers.
import base64
data = b"Hello, Python!"
encoded = base64.b64encode(data)
decoded = base64.b64decode(encoded)
print(encoded) # b'SGVsbG8sIFB5dGhvbiE='
print(decoded) # b'Hello, Python!'b64encode() takes bytes and returns bytes. The output is about 33% larger than the input because every 3 bytes of binary data become 4 Base64 characters. The trailing = is padding added when the input length is not a multiple of 3.
Encoding strings
Most data that needs Base64 encoding starts out as text, like a config value or a credential pair, rather than raw bytes. Base64 works with bytes, not strings, so convert strings to bytes first.
import base64
text = "user@example.com:api_key_12345"
encoded = base64.b64encode(text.encode()).decode()
print(encoded) # dXNlckBleGFtcGxlLmNvbTphcGlfa2V5XzEyMzQ1text.encode() converts the string to UTF-8 bytes. base64.b64encode() encodes those bytes as Base64 bytes. .decode() converts the Base64 bytes back to a string for display or insertion into text protocols.
Decoding back to original data
Decoding reverses the process: Base64 text to bytes, then optionally to a string.
import base64
encoded = "dXNlckBleGFtcGxlLmNvbTphcGlfa2V5XzEyMzQ1"
decoded_bytes = base64.b64decode(encoded)
decoded_text = decoded_bytes.decode()
print(decoded_text) # user@example.com:api_key_12345base64.b64decode() accepts both bytes and strings. The result is always bytes. Call .decode() on the result if the original data was a string.
URL-safe Base64
Standard Base64 uses + and /, which have special meanings in URLs. The URL-safe variant replaces them with - and _, though it still adds the same = padding by default.
import base64
data = b"\xfa\xce\xb0\x0c\x1a\x2b\x3c"
standard = base64.b64encode(data)
urlsafe = base64.urlsafe_b64encode(data)
print(standard) # b'+s6wDBorPA=='
print(urlsafe) # b'-s6wDBorPA=='The + becomes - and / becomes _. Use URL-safe encoding for tokens in URLs, query parameters, and filenames.
For the secrets module, use secrets.token_urlsafe() to generate URL-safe tokens directly without working with Base64 yourself.
Encoding and decoding large data
Base64 encoding works incrementally, like hashing. For large files or streams, use incremental encoding with base64.encode() and base64.decode() from the base64 module's codecs interface, or process data in chunks.
For simple file encoding:
import base64
with open("image.png", "rb") as file:
image_bytes = file.read()
encoded = base64.b64encode(image_bytes).decode()
print(f"data:image/png;base64,{encoded[:50]}...") # data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...For very large files, read and encode in chunks to manage memory, though the standard b64encode works fine for files up to a few hundred megabytes.
When to use Base64
Base64 is encoding, not encryption. It transforms data into a portable text representation but provides no security. Anyone who sees the Base64 output can decode it back to the original data.
Common uses for Base64:
- Embedding binary data (images, fonts) inside HTML, CSS, or JSON.
- Encoding credentials for HTTP Basic Authentication headers.
- Storing binary data in text-only database columns.
- Transmitting binary payloads through text-based protocols.
- Creating compact text representations of small binary values.
Do not use Base64 for:
- Encrypting sensitive data (use proper encryption libraries).
- Compressing data (Base64 makes it larger, not smaller).
- Hashing data (use hashlib).
- Generating secure tokens (use the secrets module).
Standard vs URL-safe comparison
| Feature | b64encode | urlsafe_b64encode |
|---|---|---|
| Character set | A-Z, a-z, 0-9, +, / | A-Z, a-z, 0-9, -, _ |
| Padding | = (1 or 2) | = (1 or 2, by default) |
| URL-safe | No (needs percent-encoding) | Yes |
| Filename-safe | No | Yes |
Always use URL-safe Base64 when the output appears in a URL, a query parameter, or a filename.
Practical example: embedding an image in HTML
Convert a small image to a data URI for inline HTML embedding.
import base64
from pathlib import Path
def image_data_uri(filepath):
ext = Path(filepath).suffix.lower().lstrip(".")
mime_types = {"png": "image/png", "jpg": "image/jpeg", "gif": "image/gif", "svg": "image/svg+xml"}
mime = mime_types.get(ext, "application/octet-stream")
with open(filepath, "rb") as file:
encoded = base64.b64encode(file.read()).decode()
return f"data:{mime};base64,{encoded}"Calling the function on a PNG file produces a single long string starting with the correct MIME type, which is why only the first 80 characters are printed here:
uri = image_data_uri("icon.png")
print(uri[:80] + "...")The real string continues for many more characters, but the truncated prefix is enough to confirm the MIME type and encoding were applied correctly:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...The data URI can be used directly as the src attribute of an HTML img tag. This avoids a separate HTTP request for the image but increases the HTML file size.
Common mistakes
Treating Base64 as encryption. Base64 is reversible without a key. Never use it to protect sensitive data. Anyone who sees the encoded string can recover the original data with b64decode.
Forgetting to decode the output of b64encode. b64encode() returns bytes. If you need a string (for JSON, URLs, or HTML), call .decode() on the result.
Using standard Base64 in URLs. The + and / characters require percent-encoding in URLs. Use urlsafe_b64encode() for any value that appears in a URL or filename.
Adding the wrong padding back. When you strip = padding from URL-safe Base64 and later need to decode, pass the string directly to urlsafe_b64decode. It handles the missing padding automatically.
Rune AI
Key Insights
- Use
base64.b64encode(data)to encode bytes as a Base64 byte string. - Use
base64.b64decode(encoded)to decode a Base64 string back to bytes. - Use
base64.urlsafe_b64encode()for URL and filename-safe output. - Base64 output is about 33% larger than the original binary data.
- Base64 is encoding, not encryption; it provides no confidentiality.
- Always work with bytes; encode strings to bytes before Base64 encoding.
Frequently Asked Questions
Why does Base64 encoding make data larger?
What is the difference between standard Base64 and URL-safe Base64?
Can Base64 be used for encryption?
Conclusion
The base64 module handles the most common binary-to-text encoding needs in Python. Use base64.b64encode() and base64.b64decode() for standard Base64, and base64.urlsafe_b64encode() when the output goes into a URL. Remember that Base64 is encoding, not encryption; it adds no security to your data.
More in this topic
Format Dates and Times in Python
Learn how to use strftime and strptime to format dates as strings and parse date strings into Python datetime objects.
What Is the Python Standard Library?
Learn what the Python standard library is, why it matters, and how to use its built-in modules without installing anything extra.
Python `math` Module Explained
Learn how to use the Python math module for square roots, rounding, trigonometry, logarithms, and mathematical constants.