binascii en Python: binario y ASCII

Publicado el: 18/08/2026
Tempo de leitura: 6 minutos
Código binario proyectado que representa conversiones con binascii en Python

El módulo binascii de Python reúne operaciones rápidas y de bajo nivel para convertir bytes a representaciones ASCII como hexadecimal, Base64, quoted-printable y uuencode. También incluye cálculos CRC utilizados para detectar cambios accidentales en archivos y mensajes de protocolos. Aunque la mayoría de las aplicaciones usan módulos de nivel superior, conocer binascii permite controlar mejor la validación, los errores, los buffers y los formatos binarios.

En esta guía aprenderás cuándo usar el módulo, cómo separar texto y bytes, cómo validar Base64 de forma estricta, cómo inspeccionar valores binarios en hexadecimal y por qué un CRC no equivale a un hash criptográfico. Todos los ejemplos utilizan la biblioteca estándar y son útiles en diagnósticos, procesamiento de archivos, protocolos de red e integraciones.

Qué es binascii

El nombre significa “binary to ASCII”. El módulo contiene primitivas implementadas en C para transformar datos binarios en codificaciones imprimibles y realizar la conversión inversa. Módulos de nivel superior como base64 y quopri usan estas funciones internamente.

Para código cotidiano conviene preferir las APIs superiores porque expresan mejor el estándar correspondiente. Usa binascii cuando necesites decodificación estricta, acceso directo a CRC, captura específica de excepciones o trabajo eficiente con objetos que implementan el protocolo de buffer.

Es fundamental distinguir str de bytes. Una cadena representa texto Unicode, mientras que los bytes representan octetos. Pasar de uno a otro requiere un encoding explícito, normalmente UTF-8. Puedes reforzar estos conceptos con la guía de estructuras y listas en Python y el artículo sobre slicing en Python.

Hexadecimal con hexlify y unhexlify

El formato hexadecimal resulta útil para depurar protocolos, mostrar identificadores binarios, revisar hashes y registrar campos técnicos. Cada byte produce dos dígitos hexadecimales, por lo que la salida ocupa el doble que la entrada.

import binascii

data = b"Python\x00\xff"
hex_data = binascii.hexlify(data)
print(hex_data)  # b'507974686f6e00ff'
print(binascii.unhexlify(hex_data))

b2a_hex() es un alias de hexlify(), y a2b_hex() es un alias de unhexlify(). Los nombres largos suelen ser más fáciles de entender durante una revisión de código.

También puedes insertar separadores:

direccion = b"\xaa\xbb\xcc\xdd\xee\xff"
print(binascii.hexlify(direccion, sep=b":"))
# b'aa:bb:cc:dd:ee:ff'

El método bytes.hex() devuelve texto y bytes.fromhex() tolera espacios entre grupos. unhexlify() es más estricto: exige un número par de dígitos válidos. Esa rigidez es útil cuando un campo de protocolo debe cumplir una gramática exacta.

try:
    valor = binascii.unhexlify("abc")
except binascii.Error as error:
    print(f"Hexadecimal inválido: {error}")

Conversión Base64 de bajo nivel

b2a_base64() codifica bytes en Base64. Por defecto añade un salto de línea final, siguiendo formatos tradicionales orientados por líneas. Usa newline=False para JSON, bases de datos, logs compactos o valores HTTP.

payload = b"datos binarios\x00\x01"
encoded = binascii.b2a_base64(payload, newline=False)
decoded = binascii.a2b_base64(encoded)

assert decoded == payload
print(encoded)

Base64 no cifra los datos. Cualquier persona que reciba el valor puede recuperar los bytes originales. Su objetivo es transportar binario por sistemas textuales. La guía de Base64 en Python explica además Base64 URL-safe, Base32 y Base85.

Validación estricta de Base64

La decodificación tolerante puede descartar caracteres ajenos al alfabeto. Eso es práctico en MIME con saltos de línea, pero puede ocultar una entrada malformada en una API. Desde Python 3.11, a2b_base64() admite strict_mode=True.

def decode_base64_strict(value: str) -> bytes:
    try:
        return binascii.a2b_base64(value, strict_mode=True)
    except binascii.Error as error:
        raise ValueError("Base64 inválido") from error

print(decode_base64_strict("UHl0aG9u"))

El modo estricto rechaza caracteres externos, padding inicial, padding excesivo y datos después del padding. Aun así, debes limitar el tamaño antes de decodificar. Una entrada controlada por un atacante puede consumir memoria y CPU sin necesidad.

Quoted-printable

Quoted-printable conserva legible gran parte del texto ASCII y representa otros bytes con secuencias como =C3=B1. Es común en cuerpos de correo MIME y algunas integraciones antiguas.

texto = "acción e información".encode("utf-8")
encoded = binascii.b2a_qp(texto)
decoded = binascii.a2b_qp(encoded)

print(encoded)
print(decoded.decode("utf-8"))

Las opciones header, quotetabs e istext modifican el tratamiento de espacios, tabulaciones y saltos de línea. Para correos completos usa el paquete email, que comprende cabeceras, límites MIME y políticas. Utiliza binascii cuando ya conoces exactamente el formato del campo.

CRC-32 para detectar corrupción accidental

crc32() calcula un checksum de 32 bits compatible con el utilizado en ZIP. Puede detectar alteraciones accidentales durante almacenamiento, copia o transmisión.

from pathlib import Path
import binascii

def crc32_file(path: Path, chunk_size: int = 64 * 1024) -> int:
    crc = 0
    with path.open("rb") as file:
        while chunk := file.read(chunk_size):
            crc = binascii.crc32(chunk, crc)
    return crc

result = crc32_file(Path("datos.bin"))
print(f"{result:08x}")

Procesar por bloques evita cargar un archivo grande completo en memoria. Es el mismo patrón explicado en la guía para leer archivos gigantes con Python.

CRC no sirve para contraseñas, firmas de API, tokens o protección frente a manipulación intencional. Un atacante puede cambiar el contenido y recalcular el CRC. Usa hashlib para resúmenes criptográficos y HMAC para mensajes autenticados. Las contraseñas requieren algoritmos especializados; consulta el artículo sobre hash seguro de contraseñas.

CRC-HQX en protocolos heredados

crc_hqx() implementa CRC-CCITT de 16 bits y aparece en dispositivos y formatos antiguos. El valor inicial debe coincidir con la especificación:

data = b"mensaje"
crc = binascii.crc_hqx(data, 0xffff)
print(f"{crc:04x}")

No elijas el valor inicial por intuición. Dos sistemas con el mismo polinomio pueden diferir en inicialización, reflexión de bits, orden de bytes y XOR final.

Buffers y menos copias

Las funciones aceptan objetos bytes-like, incluidos bytes, bytearray y objetos que exponen el protocolo de buffer. Un memoryview permite seleccionar una parte sin construir primero otro objeto de bytes.

buffer = bytearray(b"ABCDEF")
view = memoryview(buffer)[1:5]
print(binascii.hexlify(view))  # b'42434445'

En procesamiento incremental, un bloque puede terminar en medio de una unidad codificada. Algunas operaciones pueden lanzar binascii.Incomplete. Conserva los bytes sobrantes y añádelos al siguiente bloque en lugar de considerar toda entrada incompleta como corrupción permanente.

Manejo seguro de errores

Las entradas externas deben tratarse como no confiables. Valida tamaño y tipo antes de convertir, elige el decodificador que corresponde al formato esperado y transforma las excepciones internas en errores claros de la aplicación.

def parse_hex_field(value: str, max_chars: int = 128) -> bytes:
    if len(value) > max_chars:
        raise ValueError("Campo hexadecimal demasiado grande")
    if len(value) % 2:
        raise ValueError("Campo hexadecimal con longitud impar")
    try:
        return binascii.unhexlify(value)
    except (binascii.Error, ValueError) as error:
        raise ValueError("Campo hexadecimal inválido") from error

Evita registrar tokens, credenciales o payloads completos. Registra la operación, la longitud, la clase de error y un identificador de correlación. Así puedes diagnosticar el problema sin exponer información sensible.

Cuándo usar módulos de nivel superior

Usa base64 para Base16, Base32, Base64, Base85 y variantes URL-safe. Usa quopri o email para MIME. Usa bytes.hex() si solo necesitas una cadena sencilla. Elige binascii para primitivas de bajo nivel, CRC, validación estricta o integración eficiente con buffers.

Buenas prácticas

Documenta si una función recibe texto o bytes. Aplica límites antes de decodificar. Usa validación estricta en campos Base64 canónicos. Nunca trates un CRC como mecanismo de seguridad. Procesa archivos por bloques y captura binascii.Error en la frontera de entrada, conservando la excepción original como causa.

Conclusión

binascii es un módulo pequeño y rápido para los detalles de la conversión binaria. Sus utilidades hexadecimales, el modo Base64 estricto, quoted-printable y los CRC resultan útiles cuando una API superior no ofrece suficiente control. La clave consiste en elegir la abstracción correcta y validar explícitamente todo dato externo.

Consulta la documentación oficial de binascii y el RFC 4648 para las definiciones formales de Base16, Base32 y Base64.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    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
    A person reads 'Python for Unix and Linux System Administration' indoors.
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    base64 en Python: codifica datos

    Aprende base64 en Python para codificar bytes, usar Base64 URL-safe, validar padding, aplicar límites y diferenciar encoding de cifrado.

    Ler mais

    Tempo de leitura: 5 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