Cuando una API devuelve un campo content que parece eyJob3N0IjogImRiLXByb2Qi…, o tu gestor de secretos te entrega una credencial codificada, o necesitas extraer un payload JWT — la decodificación Base64 en Python es tu primer recurso. El módulo integrado base64 lo gestiona todo, pero los pequeños detalles sobre bytes vs cadenas, alfabetos seguros para URLs y el relleno faltante atrapan a casi todos los desarrolladores al menos una vez — he depurado esta categoría específica de errores en revisiones de código más veces de las que me gustaría admitir. Esta guía cubre base64.b64decode(), urlsafe_b64decode(), reparación automática de relleno, decodificación de archivos y respuestas HTTP, herramientas CLI, validación de entrada y cuatro errores comunes con correcciones antes/después — todos ejemplos ejecutables en Python 3.8+. Si solo necesitas una decodificación rápida sin escribir código, el Decodificador Base64 en línea de ToolDeck gestiona tanto Base64 estándar como seguro para URLs instantáneamente en tu navegador.
- ✓base64.b64decode(s) está integrado en la biblioteca estándar de Python — no requiere instalación; siempre devuelve bytes, no str.
- ✓Encadena .decode("utf-8") después de b64decode() para convertir bytes a una cadena Python — la función no conoce la codificación de texto original.
- ✓Para Base64 seguro para URLs (usa - y _ en lugar de + y /), utiliza base64.urlsafe_b64decode() — estándar en JWTs, tokens OAuth y credenciales de Google API.
- ✓Corrige el error habitual "Incorrect padding" con: padded = s + "=" * (-len(s) % 4) — añade 0, 1 o 2 caracteres según sea necesario.
- ✓Establece validate=True en cualquier entrada de fuentes externas para lanzar binascii.Error ante caracteres no Base64 en lugar de ignorarlos silenciosamente.
¿Qué es la decodificación Base64?
Base64 es un esquema de codificación que representa datos binarios arbitrarios como una cadena de 64 caracteres ASCII imprimibles: A–Z, a–z, 0–9, + y /, con = utilizado como relleno. Cada 4 caracteres Base64 codifican exactamente 3 bytes originales, por lo que la forma codificada es aproximadamente un 33% más grande que la fuente. La decodificación invierte el proceso — transformando la representación ASCII de vuelta en los bytes originales.
Base64 no cifra los datos. Es puramente una codificación de binario a texto — la cadena codificada es completamente legible por cualquiera que la pase por un decodificador:
Antes — codificado en Base64
eyJob3N0IjogImRiLXByb2QubXljb21wYW55LmludGVybmFsIiwgInBvcnQiOiA1NDMyLCAidXNlciI6ICJhcHBfc3ZjIn0=Después — decodificado
{"host": "db-prod.mycompany.internal", "port": 5432, "user": "app_svc"}base64.b64decode() — Decodificación con la biblioteca estándar
El módulo base64 de Python viene con la biblioteca estándar — sin instalación, siempre disponible. La función principal es base64.b64decode(s, altchars=None, validate=False). Acepta str, bytes o bytearray, y siempre devuelve bytes.
Ejemplo mínimo funcional
import base64
import json
# Encoded database config received from a secrets manager
encoded_config = (
"eyJob3N0IjogImRiLXByb2QubXljb21wYW55LmludGVybmFsIiwgInBvcnQiOiA1NDMyLCAid"
"XNlciI6ICJhcHBfc3ZjIiwgInBhc3N3b3JkIjogInM0ZmVQYXNzITIwMjYifQ=="
)
# Step 1: decode Base64 bytes
raw_bytes = base64.b64decode(encoded_config)
print(raw_bytes)
# b'{"host": "db-prod.mycompany.internal", "port": 5432, "user": "app_svc", "password": "s4fePass!2026"}'
# Step 2: convert bytes → str
config_str = raw_bytes.decode("utf-8")
# Step 3: parse into a dict
config = json.loads(config_str)
print(config["host"]) # db-prod.mycompany.internal
print(config["port"]) # 5432b64decode() siempre devuelve bytes — nunca una cadena. Si los datos originales eran texto, encadena .decode("utf-8"). Si eran binarios (una imagen, un PDF, un archivo gzip), mantén los bytes tal cual y escríbelos en un archivo o pásalos directamente a la biblioteca que los consuma.Ejemplo ampliado: sort_keys, ensure_ascii y validación estricta
import base64
import binascii
# Token from an internal event bus — validate strictly (external input)
encoded_event = (
"eyJldmVudCI6ICJvcmRlci5zaGlwcGVkIiwgIm9yZGVyX2lkIjogIk9SRC04ODQ3MiIsICJ"
"0aW1lc3RhbXAiOiAiMjAyNi0wMy0xM1QxNDozMDowMFoiLCAicmVnaW9uIjogImV1LXdlc3QtMSJ9"
)
try:
# validate=True raises binascii.Error on any non-Base64 character
raw = base64.b64decode(encoded_event, validate=True)
event = raw.decode("utf-8")
print(event)
# {"event": "order.shipped", "order_id": "ORD-88472", "timestamp": "2026-03-13T14:30:00Z", "region": "eu-west-1"}
except binascii.Error as exc:
print(f"Invalid Base64: {exc}")
except UnicodeDecodeError as exc:
print(f"Not UTF-8 text: {exc}")Decodificación de Base64 seguro para URLs (base64url)
El Base64 estándar usa + y /, que son caracteres reservados en URLs. La variante segura para URLs (RFC 4648 §5, también llamada “base64url”) los reemplaza con - y _. Esta es la codificación utilizada en tokens JWT, desafíos PKCE de OAuth 2.0, credenciales de Google Cloud y la mayoría de los flujos de autenticación web modernos.
Pasar Base64 seguro para URLs a b64decode() sin ajustar el alfabeto corrupta los datos silenciosamente o lanza binascii.Error. Usa base64.urlsafe_b64decode() en su lugar — gestiona la sustitución - → +y _ → / automáticamente.
import base64
import json
# JWT payload segment (the middle part between the two dots)
# JWTs use URL-safe Base64 without trailing "=" padding
jwt_payload_b64 = (
"eyJ1c2VyX2lkIjogMjg5MywgInJvbGUiOiAiYWRtaW4iLCAiaXNzIjogImF1dGgubXljb21w"
"YW55LmNvbSIsICJleHAiOiAxNzQwOTAwMDAwLCAianRpIjogImFiYzEyMzQ1LXh5ei05ODc2In0"
)
# Restore padding before decoding (JWT deliberately omits '=')
padded = jwt_payload_b64 + "=" * (-len(jwt_payload_b64) % 4)
payload_bytes = base64.urlsafe_b64decode(padded)
payload = json.loads(payload_bytes.decode("utf-8"))
print(payload["role"]) # admin
print(payload["iss"]) # auth.mycompany.com
print(payload["user_id"]) # 2893"=" * (-len(s) % 4) añade exactamente 0, 1 o 2 caracteres de relleno según sea necesario y es una operación nula cuando la cadena ya está correctamente rellenada. Es la solución idiomática de Python para los problemas de relleno en JWT y OAuth.Referencia de parámetros de base64.b64decode()
Todos los parámetros siguientes aplican tanto a b64decode() como a urlsafe_b64decode(), excepto altchars que solo está disponible en b64decode().
| Parámetro | Tipo | Por defecto | Descripción |
|---|---|---|---|
| s | bytes | str | bytearray | — | La entrada codificada en Base64 a decodificar; se acepta str ASCII junto con tipos bytes. |
| altchars | bytes | None | None | Una secuencia de 2 bytes que sustituye a + y /; permite alfabetos Base64 personalizados más allá de la variante segura para URLs estándar. |
| validate | bool | False | Cuando es True, lanza binascii.Error ante cualquier carácter fuera del alfabeto Base64; cuando es False, los bytes que no son del alfabeto (saltos de línea, espacios) se ignoran silenciosamente. |
El valor predeterminado validate=False es intencional para datos en formato PEM y Base64 multilínea (donde los saltos de línea son comunes). Para payloads de API, cargas de usuarios o cualquier entrada no confiable, pasa validate=True para detectar datos corruptos o inyectados tempranamente y mostrar un error claro.
Error de relleno al decodificar Base64 en Python — Cómo solucionarlo
El error más frecuente al decodificar Base64 en Python es:
import base64
base64.b64decode("eyJ0eXBlIjogImFjY2VzcyJ9")
# binascii.Error: Incorrect paddingBase64 requiere longitudes de cadena que sean múltiplos de 4. Cuando los datos pasan por URLs, cabeceras HTTP o bibliotecas JWT, el relleno = final se elimina para ahorrar bytes. Hay dos formas fiables de solucionarlo.
Opción 1: Restaurar el relleno en línea (recomendado)
import base64
import json
def b64decode_unpadded(data: str | bytes) -> bytes:
"""Decode Base64 with automatic padding correction."""
if isinstance(data, str):
data = data.encode("ascii")
data += b"=" * (-len(data) % 4)
return base64.b64decode(data)
# Works regardless of how many '=' were stripped
token_a = "eyJ0eXBlIjogImFjY2VzcyJ9" # 0 chars of padding stripped
token_b = "eyJ0eXBlIjogInJlZnJlc2gifQ" # 1 char stripped
token_c = "eyJ0eXBlIjogImFwaV9rZXkifQ==" # already padded
for token in (token_a, token_b, token_c):
result = json.loads(b64decode_unpadded(token).decode("utf-8"))
print(result["type"])
# access
# refresh
# api_keyOpción 2: Decodificación segura para URLs con relleno para OAuth / JWT
import base64
import json
def decode_jwt_segment(segment: str) -> dict:
"""Decode a single JWT segment (header or payload)."""
# Add padding, use URL-safe alphabet
padded = segment + "=" * (-len(segment) % 4)
raw = base64.urlsafe_b64decode(padded)
return json.loads(raw.decode("utf-8"))
# Google OAuth ID token payload (simplified)
id_token_payload = (
"eyJzdWIiOiAiMTEwNTY5NDkxMjM0NTY3ODkwMTIiLCAiZW1haWwiOiAic2FyYS5jaGVuQGV4"
"YW1wbGUuY29tIiwgImhkIjogImV4YW1wbGUuY29tIiwgImlhdCI6IDE3NDA5MDAwMDB9"
)
claims = decode_jwt_segment(id_token_payload)
print(claims["email"]) # sara.chen@example.com
print(claims["hd"]) # example.comDecodificar Base64 desde un archivo y una respuesta de API
Leer Base64 desde disco y decodificar payloads de APIs son los dos escenarios de producción más comunes. Ambos requieren un manejo adecuado de errores — el relleno corrupto y los tipos binarios inesperados son ocurrencias reales, no casos límite teóricos.
Leer y decodificar un archivo Base64
import base64
import json
from pathlib import Path
def decode_attachment(envelope_path: str, output_path: str) -> None:
"""
Read a JSON envelope with a Base64-encoded attachment,
decode it, and write the binary output to disk.
"""
try:
envelope = json.loads(Path(envelope_path).read_text(encoding="utf-8"))
encoded_data = envelope["attachment"]["data"]
file_bytes = base64.b64decode(encoded_data, validate=True)
Path(output_path).write_bytes(file_bytes)
print(f"Saved {len(file_bytes):,} bytes → {output_path}")
except FileNotFoundError:
print(f"Envelope file not found: {envelope_path}")
except (KeyError, TypeError):
print("Unexpected envelope structure — 'attachment.data' missing")
except base64.binascii.Error as exc:
print(f"Invalid Base64 content: {exc}")
# Example envelope:
# {"attachment": {"filename": "invoice_2026_03.pdf", "data": "JVBERi0xLjQK..."}}
decode_attachment("order_ORD-88472.json", "invoice_2026_03.pdf")Decodificar Base64 desde una respuesta HTTP de API
import base64
import json
import urllib.request
def fetch_and_decode_secret(vault_url: str, secret_name: str) -> str:
"""
Retrieve a Base64-encoded secret from an internal vault API
and return the decoded plaintext value.
"""
url = f"{vault_url}/v1/secrets/{secret_name}"
req = urllib.request.Request(url, headers={"X-Vault-Token": "s.internal"})
try:
with urllib.request.urlopen(req, timeout=5) as resp:
body = json.loads(resp.read().decode("utf-8"))
# Vault returns: {"data": {"value": "<base64>", "encoding": "base64"}}
encoded = body["data"]["value"]
return base64.b64decode(encoded).decode("utf-8")
except urllib.error.URLError as exc:
raise RuntimeError(f"Vault unreachable: {exc}") from exc
except (KeyError, UnicodeDecodeError, base64.binascii.Error) as exc:
raise ValueError(f"Unexpected secret format: {exc}") from exc
# db_pass = fetch_and_decode_secret("https://vault.internal", "db-prod-password")
# print(db_pass) # s4feP@ss!2026requests, reemplaza urllib.request con resp = requests.get(url, timeout=5, headers=headers) y body = resp.json(). La lógica de decodificación Base64 es idéntica.Decodificación Base64 desde la línea de comandos
Para inspección rápida en terminal — verificar un token, examinar un blob de configuración codificado o canalizar la salida de una API por un decodificador — el comando base64 está disponible en Linux y macOS. El módulo integrado -m base64 de Python funciona en todas las plataformas incluyendo Windows.
# Decode a Base64 string and print the result (Linux / macOS)
echo "eyJob3N0IjogImRiLXByb2QubXljb21wYW55LmludGVybmFsIn0=" | base64 --decode
# {"host": "db-prod.mycompany.internal"}
# Decode a file, save decoded output
base64 --decode encoded_payload.txt > decoded_output.json
# Python's cross-platform CLI decoder (works on Windows too)
python3 -m base64 -d encoded_payload.txt
# Decode a JWT payload segment inline — strip header/signature first
echo "eyJ1c2VyX2lkIjogMjg5MywgInJvbGUiOiAiYWRtaW4ifQ" | python3 -c "
import sys, base64, json
s = sys.stdin.read().strip()
padded = s + '=' * (-len(s) % 4)
print(json.dumps(json.loads(base64.urlsafe_b64decode(padded)), indent=2))
"Para trabajo exploratorio donde escribir un pipeline de shell parece excesivo, pega la cadena en el Decodificador Base64 en línea — detecta automáticamente la entrada segura para URLs y corrige el relleno al vuelo.
Validar la entrada Base64 antes de decodificar
Cuando los datos Base64 llegan de la entrada del usuario, un webhook o una API de terceros no confiable, valídalos antes de decodificar para obtener errores claros y accionables en lugar de confusos rastreos de binascii.Error en lo profundo de la lógica de negocio. Python ofrece dos enfoques: capturar excepciones o pre-validar con una expresión regular.
import base64
import binascii
import re
# ── Option A: try/except (recommended for most code paths) ──────────────────
def safe_b64decode(data: str) -> bytes | None:
"""Return decoded bytes, or None if the input is not valid Base64."""
try:
padded = data + "=" * (-len(data) % 4)
return base64.b64decode(padded, validate=True)
except (binascii.Error, ValueError):
return None
print(safe_b64decode("not-base64!!")) # None
print(safe_b64decode("eyJ0eXBlIjogInJlZnJlc2gifQ")) # b'{"type": "refresh"}'
# ── Option B: regex pre-validation ──────────────────────────────────────────
# Standard Base64 (alphabet: A-Z a-z 0-9 + /)
_STANDARD_RE = re.compile(r"^[A-Za-z0-9+/]*={0,2}$")
# URL-safe Base64 (alphabet: A-Z a-z 0-9 - _)
_URLSAFE_RE = re.compile(r"^[A-Za-z0-9-_]*={0,2}$")
def is_valid_base64(s: str) -> bool:
"""True if s is a syntactically valid standard Base64 string."""
# Length must be a multiple of 4 for fully padded strings
stripped = s.rstrip("=")
padded = stripped + "=" * (-len(stripped) % 4)
return bool(_STANDARD_RE.match(padded))
print(is_valid_base64("SGVsbG8gV29ybGQ=")) # True
print(is_valid_base64("SGVsbG8gV29ybGQ!")) # False (! is not Base64)Alternativa de alto rendimiento: pybase64
Para la gran mayoría de casos de uso, el módulo base64 de la biblioteca estándar de Python es completamente adecuado. Si estás procesando miles de payloads de API por segundo, decodificando archivos adjuntos binarios de varios megabytes en un bucle ajustado, o tu perfilador muestra las operaciones Base64 como un cuello de botella — considera pybase64. Es un wrapper de extensión en C alrededor de libbase64 y es típicamente 2–5× más rápido que la implementación de la biblioteca estándar en entradas grandes.
pip install pybase64
import pybase64
# Drop-in replacement — identical API to the stdlib base64 module
encoded_image = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12NgAAIABQ..."
image_bytes = pybase64.b64decode(encoded_image, validate=False)
print(f"Decoded {len(image_bytes):,} bytes")
# URL-safe variant — same as base64.urlsafe_b64decode()
token_bytes = pybase64.urlsafe_b64decode("eyJpZCI6IDQ3MX0=")
print(token_bytes) # b'{"id": 471}'
# Benchmark note: on strings under ~10 KB the function-call overhead dominates
# and the speedup is negligible. Profile before switching.La API es intencionalmente idéntica a base64 — cambia la importación y nada más cambia. Úsala solo cuando el perfilado confirme que Base64 es realmente un cuello de botella, lo cual es poco común fuera de los pipelines de datos de alto rendimiento.
Errores comunes
He visto estos cuatro errores repetidamente en revisiones de código — son especialmente comunes entre desarrolladores que vienen de lenguajes como JavaScript o PHP donde la decodificación Base64 devuelve una cadena directamente, o de tutoriales que omiten el manejo de errores por completo.
Error 1: Olvidar llamar a .decode() en el resultado
# ❌ b64decode() returns bytes — this crashes downstream
import base64
raw = base64.b64decode("eyJ1c2VyX2lkIjogNDcxLCAicm9sZSI6ICJhZG1pbiJ9")
# TypeError: byte indices must be integers or slices, not str
user_id = raw["user_id"]# ✅ decode bytes → str, then parse
import base64, json
raw = base64.b64decode("eyJ1c2VyX2lkIjogNDcxLCAicm9sZSI6ICJhZG1pbiJ9")
payload = json.loads(raw.decode("utf-8"))
print(payload["user_id"]) # 471
print(payload["role"]) # adminError 2: Usar b64decode() con entrada Base64 segura para URLs
# ❌ JWT and OAuth tokens use '-' and '_' — not in standard alphabet import base64 jwt_segment = "eyJ1c2VyX2lkIjogMjg5M30" # binascii.Error or silently wrong bytes — unpredictable behaviour base64.b64decode(jwt_segment)
# ✅ use urlsafe_b64decode() for any token with '-' or '_'
import base64, json
jwt_segment = "eyJ1c2VyX2lkIjogMjg5M30"
padded = jwt_segment + "=" * (-len(jwt_segment) % 4)
data = base64.urlsafe_b64decode(padded)
print(json.loads(data.decode("utf-8")))
# {'user_id': 2893}Error 3: No reparar el relleno en tokens sin él
# ❌ JWTs and most URL-transmitted tokens strip '=' — this crashes import base64 # Valid JWT payload segment — no padding, as per spec segment = "eyJ0eXBlIjogImFjY2VzcyIsICJqdGkiOiAiMzgxIn0" base64.urlsafe_b64decode(segment) # binascii.Error: Incorrect padding
# ✅ add padding before every urlsafe_b64decode() call
import base64, json
segment = "eyJ0eXBlIjogImFjY2VzcyIsICJqdGkiOiAiMzgxIn0"
padded = segment + "=" * (-len(segment) % 4)
result = json.loads(base64.urlsafe_b64decode(padded).decode("utf-8"))
print(result["type"]) # access
print(result["jti"]) # 381Error 4: Llamar a .decode("utf-8") sobre datos binarios
# ❌ Binary files (PDF, PNG, ZIP) are not UTF-8 text — this crashes
import base64
# Base64-encoded PDF starts with JVBERi... (%PDF-)
pdf_b64 = "JVBERi0xLjQKJeLjz9MKNyAwIG9iago8PC9U..."
pdf_text = base64.b64decode(pdf_b64).decode("utf-8")
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2# ✅ write binary directly to a file — no .decode() needed
import base64
from pathlib import Path
pdf_b64 = "JVBERi0xLjQKJeLjz9MKNyAwIG9iago8PC9U..."
pdf_bytes = base64.b64decode(pdf_b64)
Path("report_q1_2026.pdf").write_bytes(pdf_bytes)
print(f"Saved {len(pdf_bytes):,} bytes")Decodificación de archivos Base64 grandes en Python
Cargar un archivo Base64 de 200 MB con Path.read_text() y decodificarlo en una sola llamada asignará la cadena codificada, los bytes decodificados y cualquier representación intermedia simultáneamente — agotando fácilmente la memoria en servidores con restricciones o funciones Lambda. Para archivos más grandes de ~50–100 MB, usa un enfoque por fragmentos.
Decodificación por fragmentos a disco (sin cargar el archivo completo en RAM)
import base64
def decode_large_b64_file(input_path: str, output_path: str, chunk_size: int = 65536) -> None:
"""
Decode a large Base64 file in chunks to avoid loading the entire encoded
string into memory. chunk_size must be a multiple of 4 to keep Base64
block boundaries aligned across reads.
"""
assert chunk_size % 4 == 0, "chunk_size must be a multiple of 4"
bytes_written = 0
with open(input_path, "rb") as src, open(output_path, "wb") as dst:
while True:
chunk = src.read(chunk_size)
if not chunk:
break
# Strip whitespace that may appear in wrapped/multiline Base64
chunk = chunk.strip()
if chunk:
dst.write(base64.b64decode(chunk))
bytes_written += len(chunk)
print(f"Decoded {bytes_written:,} Base64 bytes → {output_path}")
# Example: decode a 300 MB database snapshot stored as Base64
decode_large_b64_file("snapshot_2026_03_13.b64", "snapshot_2026_03_13.sql.gz")Decodificar Base64 con base64.decodebytes() para datos PEM / multilínea
import base64
# base64.decodebytes() is designed for MIME / PEM Base64 that wraps at 76 chars.
# It silently ignores whitespace and newlines — perfect for certificate files.
with open("server_cert.pem", "rb") as f:
pem_data = f.read()
# Strip PEM headers if present, then decode
lines = [
line for line in pem_data.splitlines()
if not line.startswith(b"-----")
]
raw_cert = base64.decodebytes(b"
".join(lines))
print(f"Certificate DER payload: {len(raw_cert):,} bytes")base64.decodebytes() para certificados PEM, archivos adjuntos MIME y cualquier Base64 que se ajuste a anchos de línea fijos. Usa el enfoque por fragmentos anterior para grandes blobs opacos (copias de seguridad, archivos multimedia). Para tokens compactos de una sola línea (JWT, OAuth), b64decode() o urlsafe_b64decode() siempre es la opción correcta.Métodos de decodificación Base64 en Python — Comparación rápida
| Método | Alfabeto | Relleno | Salida | Requiere instalación | Ideal para |
|---|---|---|---|---|---|
| base64.b64decode() | Estándar (A–Z a–z 0–9 +/) | Requerido | bytes | No (stdlib) | Uso general, email, PEM |
| base64.decodebytes() | Estándar (A–Z a–z 0–9 +/) | Ignorado (elimina espacios en blanco) | bytes | No (stdlib) | Certificados PEM, adjuntos MIME, Base64 multilínea |
| base64.urlsafe_b64decode() | Seguro para URLs (A–Z a–z 0–9 -_) | Requerido | bytes | No (stdlib) | JWT, OAuth, APIs de Google Cloud |
| base64.b32decode() | 32 caracteres (A–Z, 2–7) | Requerido | bytes | No (stdlib) | Secretos TOTP, IDs seguros para DNS |
| base64.b16decode() | Hex (0–9, A–F) | Ninguno | bytes | No (stdlib) | Checksums codificados en hex, hashes |
| pybase64.b64decode() | Estándar (A–Z a–z 0–9 +/) | Requerido | bytes | Sí (pip) | Pipelines de alto rendimiento, payloads grandes |
| CLI: base64 --decode | Estándar | Auto | stdout | No (sistema) | Inspección rápida en terminal |
Usa b64decode() como tu opción predeterminada. Cambia a urlsafe_b64decode()en el momento en que veas - o _ en la entrada — esos caracteres son la señal inequívoca de Base64 seguro para URLs. Recurre a pybase64 solo después de que el perfilado confirme un cuello de botella. Para comprobaciones rápidas durante el desarrollo, el Decodificador Base64 de ToolDeck gestiona ambos alfabetos y repara el relleno automáticamente — sin necesidad de entorno Python.
Preguntas frecuentes
¿Cómo decodifico una cadena Base64 a una cadena normal en Python?
Llama a base64.b64decode(encoded) para obtener bytes, luego llama a .decode("utf-8")sobre el resultado para obtener un str de Python. Los dos pasos siempre son separados porque b64decode() solo invierte el alfabeto Base64 — no sabe si el contenido original era UTF-8, Latin-1 o binario. Si los datos usan una codificación distinta a UTF-8, pasa el nombre del codec correcto a .decode(), por ejemplo .decode("latin-1").
¿Por qué obtengo "Incorrect padding" al decodificar Base64 en Python?
Las cadenas Base64 deben tener una longitud que sea múltiplo de 4 caracteres. Los JWTs, tokens OAuth y datos transmitidos en URLs a menudo eliminan el relleno = final. Corrígelo añadiendo "=" * (-len(s) % 4) antes de decodificar. Esta fórmula añade exactamente 0, 1 o 2 caracteres según sea necesario, y es una operación nula segura cuando la cadena ya está correctamente rellenada.
¿Cuál es la diferencia entre b64decode() y urlsafe_b64decode() en Python?
Ambas decodifican el mismo algoritmo Base64 pero con diferentes alfabetos para los caracteres 62 y 63.b64decode() usa + y /; urlsafe_b64decode() usa - y _. La variante segura para URLs está definida en RFC 4648 §5 y se usa donde Base64 debe sobrevivir en URLs, cabeceras HTTP o valores de cookies sin codificación de porcentaje. Mezclarlas causa un binascii.Error o una salida corrupta silenciosamente.
¿Cómo decodifico una imagen codificada en Base64 en Python?
Decodifica a bytes con base64.b64decode(encoded), luego escribe esos bytes directamente en un archivo — no llames a .decode("utf-8") sobre datos de imagen. Si la entrada es una URL de datos (p. ej. data:image/png;base64,iVBORw0KGgo…), elimina primero el prefijo:
import base64
from pathlib import Path
# Data URL from an <img src="..."> or an API response
data_url = (
"data:image/png;base64,"
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12NgAAIABQ=="
)
# Split off the "data:image/png;base64," prefix
_, encoded = data_url.split(",", 1)
image_bytes = base64.b64decode(encoded)
Path("avatar_jsmith.png").write_bytes(image_bytes)
print(f"Saved {len(image_bytes)} bytes")¿Puedo decodificar Base64 en Python sin importar ningún módulo?
Técnicamente sí, pero no hay razón para hacerlo. El módulo base64 es parte de la biblioteca estándar de Python, siempre disponible, siempre instalado — no tiene dependencias y sus funciones están implementadas en C. Reimplementar Base64 desde cero sería más lento, más propenso a errores y más difícil de mantener. Usa siempre import base64.
¿Cómo decodifico Base64 en Python cuando la entrada es bytes, no una cadena?
base64.b64decode() acepta str, bytes y bytearray indistintamente — no se requiere conversión. Si recibes b"SGVsbG8=" de un socket o una lectura de archivo, pásalo directamente. La reparación de relleno funciona igual con bytes: data + b"=" * (-len(data) % 4) cuando se opera en modo bytes.
Herramientas relacionadas
- Base64 Encode — codifica texto o archivos binarios a Base64 instantáneamente; útil para generar fixtures de prueba para tu código de decodificación en Python sin ejecutar un script.
- JWT Decoder — inspecciona la cabecera y el payload de un JWT sin escribir código; el payload se decodifica con Base64 seguro para URLs entre bastidores, exactamente como se muestra en los ejemplos anteriores.
- URL Decode — decodifica por porcentaje cadenas de consulta y segmentos de ruta; a menudo necesario junto con la decodificación Base64 al analizar URLs de callback de OAuth o payloads de webhooks.
- URL Encode — codifica por porcentaje caracteres especiales; útil cuando necesitas incrustar un valor codificado en Base64 de forma segura dentro de un parámetro de consulta de URL.