base64 en Python: codifica datos

Publicado el: 18/08/2026
Tempo de leitura: 5 minutos
A person reads 'Python for Unix and Linux System Administration' indoors.

El módulo base64 en Python convierte bytes binarios en caracteres ASCII imprimibles y realiza la operación inversa. Permite transportar imágenes, identificadores, claves y pequeños blobs a través de formatos orientados a texto como JSON, archivos de configuración, cabeceras y algunos componentes de URL.

Base64 es una codificación, no cifrado. Cualquier persona que vea la cadena puede recuperar los bytes originales. Tampoco autentica al remitente ni protege la integridad de forma fiable. Para confidencialidad usa cifrado; para autenticidad usa MAC o firmas.

Codificación básica

import base64

datos = b"mensaje binario\x00\xff"
codificado = base64.b64encode(datos)
restaurado = base64.b64decode(codificado)

assert restaurado == datos
print(codificado)

Las funciones reciben objetos bytes-like y devuelven bytes ASCII. Para guardar el resultado en JSON, convierte en el límite:

texto = base64.b64encode(datos).decode("ascii")
original = base64.b64decode(texto)

Base64 aumenta el tamaño

Tres bytes de origen se representan con cuatro caracteres, creando aproximadamente un 33 por ciento de overhead. Base64 no comprime. Si el canal exige texto y el tamaño importa, comprime primero con un formato adecuado como zlib en Python y después codifica.

Decodificación estricta

Por defecto, b64decode() descarta caracteres fuera del alfabeto antes de comprobar el padding. Esto puede servir para texto MIME con saltos de línea, pero también aceptar basura inesperada. En APIs y tokens, utiliza validate=True:

import base64
import binascii

try:
    datos = base64.b64decode(valor, validate=True)
except (binascii.Error, ValueError) as error:
    raise ValueError("Base64 inválido") from error

Limita además la longitud de entrada y salida. Una cadena enorme puede agotar memoria antes de que los bytes decodificados sean inspeccionados.

Padding

El signo = completa el último grupo. Algunos protocolos URL-safe lo eliminan. Restaura únicamente lo necesario y documenta la regla:

import base64

def decodificar_sin_padding(texto: str) -> bytes:
    if len(texto) > 10_000:
        raise ValueError("entrada demasiado larga")
    padding = "=" * (-len(texto) % 4)
    return base64.urlsafe_b64decode(texto + padding)

No agregues padding arbitrario sin validar alfabeto y longitud. Un protocolo debe indicar si es obligatorio, opcional o prohibido.

Base64 URL-safe

urlsafe_b64encode() sustituye + por - y / por _:

import base64

identificador = base64.urlsafe_b64encode(b"archivo/2026+version")
print(identificador)
print(base64.urlsafe_b64decode(identificador))

La salida todavía puede contener =. URL-safe describe el alfabeto, no la compatibilidad automática con cualquier path o query. Construye URLs completas con urllib.parse en Python.

Alfabetos alternativos

b64encode() acepta dos bytes alternativos para + y /:

import base64

personalizado = base64.b64encode(b"datos", altchars=b"-_")
original = base64.b64decode(personalizado, altchars=b"-_", validate=True)

Usa las funciones URL-safe para el alfabeto estándar de URLs. Un alfabeto propio reduce interoperabilidad y debe documentarse.

Archivos binarios en JSON

import base64
import json
from pathlib import Path

ruta = Path("icono.png")
contenido = ruta.read_bytes()

if len(contenido) > 2 * 1024 * 1024:
    raise ValueError("el archivo supera el límite")

payload = json.dumps({
    "nombre": ruta.name,
    "contenido_base64": base64.b64encode(contenido).decode("ascii"),
})

Para archivos grandes, utiliza upload binario, multipart o almacenamiento de objetos. Base64 aumenta tráfico y puede mantener simultáneamente bytes originales, texto y bytes restaurados.

Data URLs

import base64

datos = b"..."
tipo = "image/png"
data_url = f"data:{tipo};base64,{base64.b64encode(datos).decode('ascii')}"

No confíes en el tipo declarado. Valida el formato real y aplica una allowlist. Una Data URL puede transportar HTML, SVG o scripts y provocar XSS si se inserta sin una política adecuada.

Base32

import base64

codigo = base64.b32encode(b"secreto temporal")
print(codigo)
print(base64.b32decode(codigo))

Base32 utiliza un alfabeto más pequeño y legible. b32decode() rechaza minúsculas por defecto. casefold=True las acepta. map01 permite mapear caracteres visualmente parecidos, pero el valor seguro es rechazar sustituciones ambiguas.

Base32 Hex

b32hexencode() y b32hexdecode() usan el alfabeto hexadecimal extendido de RFC 4648. Los dígitos 0 y 1 forman parte real del alfabeto y no se sustituyen por letras.

Base16

import base64

hexadecimal = base64.b16encode(b"ABC")
print(hexadecimal)
print(base64.b16decode(hexadecimal))

La decodificación acepta mayúsculas por defecto. Activa casefold solo si el protocolo permite minúsculas. Para identificadores hexadecimales normales, bytes.hex() y bytes.fromhex() pueden ser más directos.

Ascii85, Base85 y Z85

Las familias Base85 representan cuatro bytes con cinco caracteres y tienen menos overhead que Base64. Python ofrece variantes incompatibles:

  • a85encode(): Ascii85 para PostScript y PDF.
  • b85encode(): variante utilizada por herramientas como Git.
  • z85encode(): Z85 de ZeroMQ, disponible desde Python 3.13.
import base64

datos = b"12345678"
print(base64.a85encode(datos))
print(base64.b85encode(datos))
print(base64.z85encode(datos))

No son intercambiables. Sigue la especificación externa para alfabeto, padding, marcadores y espacios.

Reglas de longitud de Z85

Z85 exige entrada múltiplo de cuatro y salida múltiplo de cinco. Si añades padding, conserva también la longitud original o define una regla inequívoca para eliminarlo.

Interfaz MIME antigua

encodebytes() inserta saltos de línea cada 76 caracteres. Para mensajes de correo completos, usa el paquete email, que gestiona cabeceras, transfer encoding y multipart. Las funciones modernas son mejores para APIs.

HTTP Basic Authentication

Basic Authentication codifica usuario:contraseña con Base64. La codificación no protege las credenciales; TLS proporciona confidencialidad durante el transporte.

import base64

credenciales = "usuario:contraseña".encode("utf-8")
header = "Basic " + base64.b64encode(credenciales).decode("ascii")

No registres el header y evita contraseñas compartidas de larga duración.

No almacenes contraseñas con Base64

Una contraseña codificada equivale a texto plano. Usa un algoritmo de hash para contraseñas con salt y coste configurable. Las claves y tokens deben almacenarse cifrados o en un gestor de secretos.

Tokens firmados

JWT utiliza Base64URL para representar secciones, pero la seguridad proviene de la firma o MAC. Decodificar un token no lo verifica. Comprueba algoritmo, clave, firma, issuer, audience, expiración y claims con una biblioteca adecuada.

Decodificación con límites

import base64
import binascii

MAX_TEXTO = 4 * 1024 * 1024
MAX_SALIDA = 3 * 1024 * 1024

def decodificar_limitado(texto: str) -> bytes:
    if len(texto) > MAX_TEXTO:
        raise ValueError("Base64 supera el límite")
    try:
        datos = base64.b64decode(texto, validate=True)
    except binascii.Error as error:
        raise ValueError("Base64 inválido") from error
    if len(datos) > MAX_SALIDA:
        raise ValueError("la salida supera el límite")
    return datos

La relación de tamaños ayuda a calcular un máximo, pero los bytes resultantes todavía deben validarse según el formato declarado.

Comparación constante

Si los bytes son un MAC o firma esperada, compara con hmac.compare_digest() después de validar longitud y formato. Esto reduce diferencias de tiempo de una igualdad normal.

Payloads binarios estructurados

Base64 transporta bytes, pero no define el layout. Usa struct en Python para cabeceras versionadas con magic y límites. Los lotes pueden procesarse con queue en Python para aplicar backpressure.

Pruebas recomendadas

Prueba entrada vacía, longitudes módulo cuatro, padding ausente o excesivo, caracteres inválidos, Unicode no ASCII, alfabetos estándar y URL-safe, límites, caracteres ambiguos de Base32, padding de Base85, round trips aleatorios y vectores de RFC 4648.

Buenas prácticas

  • Trabaja internamente con bytes.
  • Convierte a ASCII en el límite.
  • Usa validate=True.
  • Define límites antes y después.
  • Selecciona el alfabeto según la especificación.
  • No confundas encoding con seguridad.
  • No registres credenciales ni tokens.
  • Valida los bytes decodificados.

Conclusión

base64 en Python ofrece Base16, Base32, Base64, Ascii85, Base85 y Z85 para transportar bytes en canales textuales. La API es simple, pero los sistemas robustos necesitan validación estricta, límites y un protocolo claro.

Consulta la documentación oficial de base64 y la RFC 4648. La codificación resuelve representación; confidencialidad y autenticidad requieren herramientas específicas.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Código binario proyectado que representa conversiones con binascii en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    binascii en Python: binario y ASCII

    Aprende binascii en Python para convertir hexadecimal, Base64 y quoted-printable, calcular CRC y validar datos binarios de forma segura.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    codecs en Python: domina encodings

    Aprende codecs en Python para usar encodings, handlers, BOM, streams incrementales y migrar codecs.open a open.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    Detailed image of a Burmese Python being held. Captured in Toluca, Mexico.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    urllib.parse en Python: maneja URLs

    Aprende urllib.parse en Python para dividir URLs, crear queries, codificar componentes y evitar riesgos con urljoin, redirects, logs y SSRF.

    Ler mais

    Tempo de leitura: 5 minutos
    18/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    ipaddress en Python: redes IPv4 e IPv6

    Aprende ipaddress en Python para validar IPv4 e IPv6, calcular redes CIDR, dividir subredes y crear políticas de acceso más

    Ler mais

    Tempo de leitura: 5 minutos
    18/08/2026
    A developer typing code on a laptop with a Python book beside in an office.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    queue en Python: coordina hilos

    Aprende queue en Python para coordinar hilos con FIFO, prioridad, backpressure, tracking, reintentos y shutdown seguro.

    Ler mais

    Tempo de leitura: 4 minutos
    17/08/2026
    Chic portrait of a woman wearing trendy sunglasses reflecting numbers, captured in a modern setting.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    struct en Python: datos binarios

    Aprende struct en Python para empaquetar datos binarios, controlar endianness, reutilizar buffers y validar protocolos externos.

    Ler mais

    Tempo de leitura: 4 minutos
    17/08/2026