I keep coming back to base64 whenever I’m working with APIs, JWT tokens, or any system that needs to safely transmit binary data as text. The other day I needed to decode a webhook payload that came in as a base64 string, and I thought – I should write down exactly how I did this, because the gotchas are real.

Base64 is one of those tools that looks simple on the surface but trips up a lot of people. You take some bytes, you get a string. You take the string back, you get bytes. Easy – except the encode/decode dance between strings and bytes in Python trips up almost everyone at least once. Let me walk you through exactly how it works.

TLDR

  • Use Python’s built-in base64 module – no pip install needed
  • Always work with bytes, not strings, when encoding or decoding
  • The b64decode function returns bytes – call .decode() if you need a string
  • Use urlsafe variants (urlsafe_b64encode, urlsafe_b64decode) when working with URLs or filenames
  • InvalidBase64Error and binascii.Error tell you when padding is wrong

What is Base64?

Base64 is an encoding scheme that converts binary data into ASCII text. It does this by mapping each 6 bits of input to one of 64 characters: uppercase A-Z, lowercase a-z, digits 0-9, plus (+), and forward slash (/). The equals sign (=) is used for padding at the end.

You see base64 everywhere – JWT tokens, HTTP Basic Auth, email attachments, APIs that return binary data as text, and configuration files that need to store binary safely. Python ships with a built-in base64 module that handles all of this for you.

Decoding a Base64 String in Python

Here is the simplest way to decode a base64 string in Python. I start with a variable holding the encoded text as a string, encode it to bytes using ASCII, then pass those bytes to b64decode.

Description: Basic base64 decode from string to string.


import base64

encoded = "QXNrUHl0aG9uLmNvbSBpcyB0aGUgYmVzdCE="
decoded_bytes = base64.b64decode(encoded)
decoded_text = decoded_bytes.decode('utf-8')
print(decoded_text)

Explain code: First we .encode() the string to ASCII bytes. Then b64decode turns those bytes back into the original binary data. Finally we .decode(‘utf-8’) to get a readable string. Each step is necessary – skip the encode step and Python throws a TypeError.

Output:


AskPython.com is the best!

Description: Decode base64 directly from a string variable.


import base64

SERVICE_CONFIG = "SGVsbG8gV29ybGQh"
decoded_bytes = base64.b64decode(SERVICE_CONFIG)
print(decoded_bytes)

Explain code: b64decode returns raw bytes, not a string. Printing bytes shows the byte notation like b’Hello World!’. If you need the actual text, add .decode(‘utf-8’).

Output:

URL-Safe Base64 Decoding

Standard base64 uses + and / characters. In URLs and filenames, those characters cause problems – URLs strip +, and some filesystems mishandle /. Python provides urlsafe_b64decode for exactly this situation. It replaces + with – and / with _.

Description: Decode URL-safe base64 strings that use – and _ instead of + and /.


import base64

urlsafe_encoded = "SGVsbG8-V29ybGQh"
decoded = base64.urlsafe_b64decode(urlsafe_encoded)
print(decoded.decode('utf-8'))

Explain code: urlsafe_b64decode handles the – and _ replacement automatically. Pass it the URL-safe string and you get back the original bytes. Works the same as b64decode otherwise.

Output:

Handling Padding Errors

Base64 strings need proper padding with = signs to decode correctly. If you get binascii.Error: Incorrect padding, you have a few options. The most reliable fix is to manually add padding until the string length is divisible by 4.

Description: Fix invalid padding in base64 strings before decoding.


import base64

def decode_b64_strict(data):
    CRED = data.strip()
    missing_padding = len(CRED) % 4
    if missing_padding:
        CRED += '=' * (4 - missing_padding)
    return base64.b64decode(CRED)

SERVICE_CONFIG = "SGVsbG8"  # no padding
result = decode_b64_strict(SERVICE_CONFIG)
print(result.decode('utf-8'))

Explain code: This function calculates how many = signs are needed (0 to 3) and adds them before calling b64decode. Stripping whitespace first handles cases where the string has newlines or spaces.

Output:

Decoding Files and Binary Data

When you need to decode base64 data from a file or a large payload, read the file first and then decode. Here I read a file containing base64 text and write the decoded binary output to a new file.

Description: Read a base64-encoded file and write decoded bytes to disk.


import base64

with open('encoded_data.txt', 'r') as f:
    encoded_data = f.read().strip()

decoded_bytes = base64.b64decode(encoded_data)

with open('output.bin', 'wb') as f:
    f.write(decoded_bytes)

print("Decoded and saved to output.bin")

Explain code: Read the entire file as a string, strip whitespace, pass to b64decode which returns bytes, then write those bytes to a binary file with ‘wb’ mode. Reading as text and writing as binary is the standard pattern.

Output:


Decoded and saved to output.bin

FAQ

Q: Why does b64decode require bytes and not a string?

Base64 is designed to encode binary data. The b64decode function operates on bytes because base64 is at its core a transformation from bytes to ASCII text and back. If you pass a string, Python first tries to encode it to bytes using ASCII, which can cause unexpected results for non-ASCII strings.

Q: How do I decode a JWT token payload?

JWT tokens have three parts separated by dots. The payload (middle part) is URL-safe base64. Split the token on dots, take the second part, and decode it with urlsafe_b64decode. Add padding if needed.

Q: Can I decode base64 that contains non-ASCII characters?

Yes, but you need to specify the correct encoding when decoding. For UTF-8 strings, use .decode(‘utf-8’) after b64decode. For other encodings like Latin-1, specify that instead.

Q: What is the difference between b64decode and standard base64 decoding?

There is no difference – b64decode is the standard base64 decoding function in Python’s base64 module. The function name is simply shorthand for “base64 decode”.

Q: Is base64 encryption?

No. Base64 is encoding, not encryption. Anyone who knows the scheme can reverse it instantly. Use it to safely transmit or store binary data as text, not to hide information.

Quick Reference

Description: Complete encoding and decoding cheat sheet.


import base64

data = "Hello"

# Encode to base64
encoded = base64.b64encode(data.encode('utf-8'))
print(encoded)

# Decode from base64
decoded = base64.b64decode(encoded)
print(decoded.decode('utf-8'))

# URL-safe variants
url_encoded = base64.urlsafe_b64encode(data.encode('utf-8'))
url_decoded = base64.urlsafe_b64decode(url_encoded)
print(url_decoded.decode('utf-8'))

Explain code: b64encode takes bytes and returns base64 ASCII bytes. b64decode reverses this. urlsafe variants swap +/ for -_ to make output safe for URLs and filenames.

Output:


b'SGVsbG8='
b'Hello'
b'Hello'

Share.
Leave A Reply