1926 words
10 minutes
Python Base64 Module - Complete Guide
🔐 Python Base64 Module - Complete Guide

📚 Table of Contents
- What is Base64?
- Why Use Base64?
- Basic Encoding
- Basic Decoding
- URL-Safe Base64
- Base32 Encoding
- Base16 (Hex) Encoding
- Base85 Encoding
- Encoding Files
- Encoding Images
- Data URLs
- Working with JSON
- Security Considerations
- Common Use Cases
- Practical Projects
1. What is Base64?
![]()
Base64 is an encoding scheme that converts binary data into ASCII text.
How It Works
- Takes 3 bytes (24 bits) of data
- Splits into 4 groups of 6 bits each
- Maps each 6-bit group to a character (A-Z, a-z, 0-9, +, /)
Base64 Character Set
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/Example
Text: "Hi"Binary: 01001000 01101001Base64: SGk=2. Why Use Base64?
Common Uses
| Use Case | Description |
|---|---|
| Email attachments | MIME encoding |
| Embedding images | Data URLs in HTML |
| API data transfer | JSON/XML payloads |
| Storing binary in text | Databases, configs |
| Basic obfuscation | Hide readable text |
| Authentication | HTTP Basic Auth |
Pros and Cons
Pros:
- ✅ Text-safe (no special characters)
- ✅ Works everywhere
- ✅ Reversible
Cons:
- ❌ ~33% size increase
- ❌ NOT encryption (easily decoded)
3. Basic Encoding
Import the Module
import base64Encode String
import base64
# Original texttext = "Hello, World!"
# Encode (string → bytes → base64 bytes → base64 string)encoded_bytes = base64.b64encode(text.encode('utf-8'))encoded_string = encoded_bytes.decode('utf-8')
print(f"Original: {text}")print(f"Encoded: {encoded_string}")
# Output:# Original: Hello, World!# Encoded: SGVsbG8sIFdvcmxkIQ==Simple One-Liner
import base64
# Encodeencoded = base64.b64encode(b"Hello").decode()print(encoded) # SGVsbG8=
# Alternative with stringtext = "Hello, World!"encoded = base64.b64encode(text.encode()).decode()print(encoded) # SGVsbG8sIFdvcmxkIQ==Encode Bytes Directly
import base64
# Binary datadata = bytes([0x48, 0x65, 0x6c, 0x6c, 0x6f]) # "Hello" in bytes
encoded = base64.b64encode(data)print(encoded) # b'SGVsbG8='4. Basic Decoding
Decode Base64 String
import base64
# Base64 encoded stringencoded = "SGVsbG8sIFdvcmxkIQ=="
# Decode (base64 string → bytes → string)decoded_bytes = base64.b64decode(encoded)decoded_string = decoded_bytes.decode('utf-8')
print(f"Encoded: {encoded}")print(f"Decoded: {decoded_string}")
# Output:# Encoded: SGVsbG8sIFdvcmxkIQ==# Decoded: Hello, World!Simple One-Liner
import base64
# Decodedecoded = base64.b64decode("SGVsbG8sIFdvcmxkIQ==").decode()print(decoded) # Hello, World!Handle Errors
import base64
def safe_decode(encoded_string): try: decoded = base64.b64decode(encoded_string).decode('utf-8') return decoded except Exception as e: return f"Error: {e}"
# Testprint(safe_decode("SGVsbG8=")) # Helloprint(safe_decode("Invalid!!!")) # Error: ...5. URL-Safe Base64
Standard Base64 uses + and / which are not URL-safe. URL-safe Base64 replaces them with - and _.
Encode URL-Safe
import base64
text = "Hello?World+Test"
# Standard Base64standard = base64.b64encode(text.encode()).decode()print(f"Standard: {standard}")
# URL-Safe Base64url_safe = base64.urlsafe_b64encode(text.encode()).decode()print(f"URL-Safe: {url_safe}")
# Output:# Standard: SGVsbG8/V29ybGQrVGVzdA==# URL-Safe: SGVsbG8_V29ybGQrVGVzdA==Decode URL-Safe
import base64
encoded = "SGVsbG8_V29ybGQrVGVzdA=="
decoded = base64.urlsafe_b64decode(encoded).decode()print(decoded) # Hello?World+TestComparison
| Character | Standard | URL-Safe |
|---|---|---|
| Plus | + | - |
| Slash | / | _ |
| Padding | = | = |
6. Base32 Encoding
Base32 uses only uppercase letters A-Z and digits 2-7. Useful when case-insensitive encoding is needed.
Encode Base32
import base64
text = "Hello"
# Encodeencoded = base64.b32encode(text.encode()).decode()print(f"Base32: {encoded}") # JBSWY3DP
# Decodedecoded = base64.b32decode(encoded).decode()print(f"Decoded: {decoded}") # HelloBase32 Character Set
ABCDEFGHIJKLMNOPQRSTUVWXYZ234567Use Cases
- TOTP/HOTP tokens (Google Authenticator)
- File systems that aren’t case-sensitive
- Human-readable codes
7. Base16 (Hex) Encoding
Base16 is essentially hexadecimal encoding.
Encode/Decode Hex
import base64
text = "Hello"
# Encode to hexhex_encoded = base64.b16encode(text.encode()).decode()print(f"Hex: {hex_encoded}") # 48656C6C6F
# Decode from hexdecoded = base64.b16decode(hex_encoded).decode()print(f"Decoded: {decoded}") # HelloAlternative: Built-in hex()
# Using bytes methodtext = "Hello"
# Encodehex_str = text.encode().hex()print(hex_str) # 48656c6c6f
# Decodedecoded = bytes.fromhex(hex_str).decode()print(decoded) # Hello8. Base85 Encoding
Base85 is more efficient than Base64 (only ~25% size increase vs ~33%).
ASCII85 Encoding
import base64
text = "Hello, World!"
# Encodeencoded = base64.a85encode(text.encode()).decode()print(f"ASCII85: {encoded}")
# Decodedecoded = base64.a85decode(encoded).decode()print(f"Decoded: {decoded}")Base85 Encoding
import base64
text = "Hello, World!"
# Encodeencoded = base64.b85encode(text.encode()).decode()print(f"Base85: {encoded}")
# Decodedecoded = base64.b85decode(encoded).decode()print(f"Decoded: {decoded}")Comparison
| Encoding | Size Increase | Characters |
|---|---|---|
| Base64 | ~33% | 64 |
| Base85 | ~25% | 85 |
| Base32 | ~60% | 32 |
| Base16 | 100% | 16 |
9. Encoding Files
Encode File to Base64
import base64
def encode_file(filepath): """Read file and return Base64 encoded string""" with open(filepath, "rb") as f: data = f.read() encoded = base64.b64encode(data).decode() return encoded
# Usageencoded_content = encode_file("document.pdf")print(encoded_content[:100]) # First 100 chars
# Save encoded to filewith open("document.b64", "w") as f: f.write(encoded_content)Decode Base64 to File
import base64
def decode_file(encoded_string, output_path): """Decode Base64 string and save to file""" decoded = base64.b64decode(encoded_string) with open(output_path, "wb") as f: f.write(decoded)
# Usagewith open("document.b64", "r") as f: encoded_content = f.read()
decode_file(encoded_content, "restored_document.pdf")Encode Large Files (Streaming)
import base64
def encode_file_streaming(input_path, output_path): """Encode large file in chunks""" with open(input_path, "rb") as fin: with open(output_path, "wb") as fout: while True: # Read in chunks of 57 bytes (produces 76 Base64 chars) chunk = fin.read(57) if not chunk: break encoded = base64.b64encode(chunk) fout.write(encoded) fout.write(b"\n") # Add newline for readability
encode_file_streaming("large_file.zip", "large_file.b64")10. Encoding Images
Encode Image to Base64
import base64
def image_to_base64(image_path): """Convert image to Base64 string""" with open(image_path, "rb") as f: data = f.read() return base64.b64encode(data).decode()
# Usageimage_b64 = image_to_base64("photo.jpg")print(f"Length: {len(image_b64)} characters")print(f"Preview: {image_b64[:50]}...")Decode Base64 to Image
import base64
def base64_to_image(b64_string, output_path): """Convert Base64 string back to image""" data = base64.b64decode(b64_string) with open(output_path, "wb") as f: f.write(data)
# Usagebase64_to_image(image_b64, "restored_photo.jpg")With PIL/Pillow
import base64from PIL import Imageimport io
# Image to Base64def pil_to_base64(image): buffer = io.BytesIO() image.save(buffer, format="PNG") return base64.b64encode(buffer.getvalue()).decode()
# Base64 to Imagedef base64_to_pil(b64_string): data = base64.b64decode(b64_string) return Image.open(io.BytesIO(data))
# Usageimg = Image.open("photo.png")b64 = pil_to_base64(img)
restored_img = base64_to_pil(b64)restored_img.show()11. Data URLs
Data URLs embed data directly in HTML/CSS.
Format
data:[<mediatype>][;base64],<data>Create Image Data URL
import base64
def image_to_data_url(image_path): """Create data URL from image""" # Determine MIME type extension = image_path.split(".")[-1].lower() mime_types = { "jpg": "image/jpeg", "jpeg": "image/jpeg", "png": "image/png", "gif": "image/gif", "svg": "image/svg+xml", "webp": "image/webp" } mime_type = mime_types.get(extension, "application/octet-stream")
# Encode image with open(image_path, "rb") as f: data = base64.b64encode(f.read()).decode()
return f"data:{mime_type};base64,{data}"
# Usagedata_url = image_to_data_url("logo.png")print(data_url)
# Use in HTMLhtml = f'<img src="{data_url}" alt="Logo">'Common Data URL Types
# Texttext_url = f"data:text/plain;base64,{base64.b64encode(b'Hello').decode()}"
# HTMLhtml_content = "<h1>Hello</h1>"html_url = f"data:text/html;base64,{base64.b64encode(html_content.encode()).decode()}"
# JSONimport jsonjson_data = {"name": "Ahmed", "age": 25}json_url = f"data:application/json;base64,{base64.b64encode(json.dumps(json_data).encode()).decode()}"
# PDFwith open("doc.pdf", "rb") as f: pdf_url = f"data:application/pdf;base64,{base64.b64encode(f.read()).decode()}"12. Working with JSON
Encode JSON Data
import base64import json
# Data to encodedata = { "name": "Ahmed", "age": 25, "skills": ["Python", "Hacking"], "active": True}
# Convert to JSON string, then Base64json_string = json.dumps(data)encoded = base64.b64encode(json_string.encode()).decode()
print(f"JSON: {json_string}")print(f"Base64: {encoded}")Decode JSON Data
import base64import json
encoded = "eyJuYW1lIjogIkFobWVkIiwgImFnZSI6IDI1fQ=="
# Decode Base64, then parse JSONjson_string = base64.b64decode(encoded).decode()data = json.loads(json_string)
print(f"Name: {data['name']}")print(f"Age: {data['age']}")Nested Encoding
import base64import json
# Sometimes APIs use Base64-encoded JSON in JSONpayload = { "type": "message", "data": base64.b64encode(json.dumps({ "text": "Hello", "timestamp": 1234567890 }).encode()).decode()}
# To read it:inner_data = json.loads(base64.b64decode(payload["data"]).decode())print(inner_data) # {'text': 'Hello', 'timestamp': 1234567890}13. Security Considerations
⚠️ Base64 is NOT Encryption!
import base64
# This is NOT secure!password = "secret123"encoded = base64.b64encode(password.encode()).decode()
print(f"Encoded: {encoded}") # c2VjcmV0MTIz
# Anyone can decode it!decoded = base64.b64decode(encoded).decode()print(f"Decoded: {decoded}") # secret123When to Use
| ✅ Use For | ❌ Don’t Use For |
|---|---|
| Data transport | Password storage |
| Embedding data | Encryption |
| Text-safe encoding | Hiding secrets |
| Binary in text | Security |
Proper Encryption Example
import base64from cryptography.fernet import Fernet # pip install cryptography
# Generate key (store this securely!)key = Fernet.generate_key()cipher = Fernet(key)
# Encryptmessage = "Secret message"encrypted = cipher.encrypt(message.encode())print(f"Encrypted: {encrypted}")
# Decryptdecrypted = cipher.decrypt(encrypted).decode()print(f"Decrypted: {decrypted}")14. Common Use Cases
HTTP Basic Authentication
import base64import requests
def basic_auth(username, password): """Create Basic Auth header""" credentials = f"{username}:{password}" encoded = base64.b64encode(credentials.encode()).decode() return f"Basic {encoded}"
# Usageheaders = { "Authorization": basic_auth("admin", "secret123")}
# Makes: Authorization: Basic YWRtaW46c2VjcmV0MTIzresponse = requests.get("https://api.example.com", headers=headers)Email Attachments (MIME)
import base64from email.mime.base import MIMEBasefrom email import encoders
def create_attachment(filepath): """Create email attachment""" with open(filepath, "rb") as f: data = f.read()
# Encode for email encoded = base64.b64encode(data).decode()
# Split into lines of 76 characters (MIME standard) lines = [encoded[i:i+76] for i in range(0, len(encoded), 76)] return "\n".join(lines)
attachment_data = create_attachment("document.pdf")JWT Tokens (Without Signature Verification)
import base64import json
def decode_jwt_payload(token): """Extract payload from JWT (don't use for security!)""" parts = token.split(".") if len(parts) != 3: raise ValueError("Invalid JWT format")
# Payload is the second part (with padding fix) payload_b64 = parts[1] # Add padding if needed padding = 4 - len(payload_b64) % 4 if padding != 4: payload_b64 += "=" * padding
payload_json = base64.urlsafe_b64decode(payload_b64).decode() return json.loads(payload_json)
# Example JWTtoken = "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiQWhtZWQiLCJyb2xlIjoiYWRtaW4ifQ.signature"payload = decode_jwt_payload(token)print(payload) # {'name': 'Ahmed', 'role': 'admin'}Obfuscation (Not Security!)
import base64
def simple_obfuscate(text, layers=3): """Multiple Base64 encoding layers (NOT SECURE!)""" result = text.encode() for _ in range(layers): result = base64.b64encode(result) return result.decode()
def simple_deobfuscate(encoded, layers=3): """Reverse multiple Base64 encoding""" result = encoded.encode() for _ in range(layers): result = base64.b64decode(result) return result.decode()
# Usageoriginal = "Secret Message"obfuscated = simple_obfuscate(original)print(f"Obfuscated: {obfuscated}")
restored = simple_deobfuscate(obfuscated)print(f"Restored: {restored}")15. Practical Projects
Project 1: Image to HTML Converter
import base64import os
def create_html_with_images(folder_path, output_html): """Create HTML page with embedded images""" html = """<!DOCTYPE html><html><head> <title>Image Gallery</title> <style> body { font-family: Arial; padding: 20px; background: #222; } .gallery { display: flex; flex-wrap: wrap; gap: 10px; } .gallery img { max-width: 300px; border-radius: 10px; } </style></head><body> <h1 style="color: white;">Image Gallery</h1> <div class="gallery">"""
for filename in os.listdir(folder_path): if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')): filepath = os.path.join(folder_path, filename)
# Determine MIME type ext = filename.split('.')[-1].lower() mime = f"image/{'jpeg' if ext == 'jpg' else ext}"
# Encode image with open(filepath, "rb") as f: b64 = base64.b64encode(f.read()).decode()
html += f' <img src="data:{mime};base64,{b64}" alt="{filename}">\n'
html += """ </div></body></html>"""
with open(output_html, "w") as f: f.write(html)
print(f"Created: {output_html}")
# Usage# create_html_with_images("./images", "gallery.html")Project 2: Base64 Encoder/Decoder CLI
import base64import argparseimport sys
def main(): parser = argparse.ArgumentParser(description="Base64 Encoder/Decoder") parser.add_argument("action", choices=["encode", "decode"], help="Action to perform") parser.add_argument("-t", "--text", help="Text to encode/decode") parser.add_argument("-f", "--file", help="File to encode/decode") parser.add_argument("-o", "--output", help="Output file") parser.add_argument("-u", "--urlsafe", action="store_true", help="Use URL-safe Base64")
args = parser.parse_args()
# Get input data if args.text: data = args.text.encode() if args.action == "encode" else args.text elif args.file: mode = "rb" if args.action == "encode" else "r" with open(args.file, mode) as f: data = f.read() if args.action == "encode" else f.read() else: print("Provide --text or --file") sys.exit(1)
# Process if args.action == "encode": if args.urlsafe: result = base64.urlsafe_b64encode(data).decode() else: result = base64.b64encode(data).decode() else: if args.urlsafe: result = base64.urlsafe_b64decode(data) else: result = base64.b64decode(data) if isinstance(result, bytes): result = result.decode()
# Output if args.output: mode = "w" if isinstance(result, str) else "wb" with open(args.output, mode) as f: f.write(result) print(f"Saved to: {args.output}") else: print(result)
if __name__ == "__main__": main()
# Usage:# python base64_tool.py encode -t "Hello World"# python base64_tool.py decode -t "SGVsbG8gV29ybGQ="# python base64_tool.py encode -f image.png -o image.b64# python base64_tool.py decode -f image.b64 -o restored.pngProject 3: Simple Data Steganography
import base64
def hide_in_spaces(cover_text, secret_message): """Hide message in whitespace (tabs vs spaces)""" # Encode secret to binary secret_b64 = base64.b64encode(secret_message.encode()).decode() binary = ''.join(format(ord(c), '08b') for c in secret_b64)
# Add length header length_bin = format(len(binary), '016b') binary = length_bin + binary
# Replace spaces based on binary result = [] bin_index = 0
for char in cover_text: if char == ' ' and bin_index < len(binary): # 0 = space, 1 = tab result.append('\t' if binary[bin_index] == '1' else ' ') bin_index += 1 else: result.append(char)
return ''.join(result)
def extract_from_spaces(stego_text): """Extract hidden message from whitespace""" # Extract binary from spaces/tabs binary = '' for char in stego_text: if char in ' \t': binary += '1' if char == '\t' else '0'
# Get length length = int(binary[:16], 2) data_binary = binary[16:16+length]
# Convert binary to characters chars = [chr(int(data_binary[i:i+8], 2)) for i in range(0, len(data_binary), 8)] secret_b64 = ''.join(chars)
# Decode Base64 return base64.b64decode(secret_b64).decode()
# Usagecover = "This is a normal looking text with many spaces for hiding data"secret = "Secret!"
stego = hide_in_spaces(cover, secret)print(f"Stego text: {repr(stego)}")
extracted = extract_from_spaces(stego)print(f"Extracted: {extracted}")Project 4: QR Code Generator with Base64
import base64import qrcode # pip install qrcode[pil]import io
def data_to_qr(data, output_path="qr.png"): """Convert data to QR code""" # Encode data encoded = base64.b64encode(data.encode()).decode()
# Generate QR code qr = qrcode.QRCode(version=1, box_size=10, border=5) qr.add_data(encoded) qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white") img.save(output_path)
print(f"QR code saved: {output_path}") return output_path
def qr_to_data(qr_image_path): """Read QR code and decode data""" from pyzbar.pyzbar import decode # pip install pyzbar from PIL import Image
img = Image.open(qr_image_path) decoded = decode(img)
if decoded: encoded = decoded[0].data.decode() return base64.b64decode(encoded).decode() return None
# Usage# data_to_qr("Secret message in QR code!")# message = qr_to_data("qr.png")# print(message)🎯 Quick Reference
| Function | Description |
|---|---|
b64encode(data) | Encode to Base64 |
b64decode(data) | Decode from Base64 |
urlsafe_b64encode() | URL-safe encoding |
urlsafe_b64decode() | URL-safe decoding |
b32encode() | Base32 encoding |
b32decode() | Base32 decoding |
b16encode() | Hex encoding |
b16decode() | Hex decoding |
a85encode() | ASCII85 encoding |
b85encode() | Base85 encoding |
🎉 You’ve Mastered Base64!
Now you can:
- Encode/decode any data
- Work with files and images
- Create data URLs
- Understand common use cases
- Build practical tools
Remember: Base64 is encoding, NOT encryption!
Created by cat0x01 🥷🏻