binascii no Python: binário e ASCII

Publicado em: 18/08/2026
Tempo de leitura: 6 minutos
Código binário projetado representando conversões com binascii no Python

O módulo binascii do Python reúne operações rápidas de conversão entre bytes e representações ASCII, como hexadecimal, Base64, quoted-printable e uuencode. Ele também oferece cálculos de CRC usados para detectar alterações acidentais em arquivos e protocolos. Embora normalmente você trabalhe com módulos de nível mais alto, como base64, conhecer binascii ajuda a entender o que acontece por baixo dessas APIs e a tratar entradas inválidas de forma mais precisa.

Este guia mostra quando usar o módulo, como diferenciar texto de bytes, como validar Base64 estritamente, como converter dados hexadecimais e por que CRC não deve ser confundido com hash criptográfico. Os exemplos usam somente a biblioteca padrão e funcionam bem em scripts, integrações de rede, ferramentas de diagnóstico e processamento de arquivos.

O que é o módulo binascii?

binascii contém funções de baixo nível, implementadas em C, para converter dados binários em formatos ASCII e fazer o caminho inverso. O nome vem de “binary to ASCII”. Muitas funções dos módulos base64 e quopri usam essa camada internamente.

Na maioria das aplicações, prefira as APIs de nível mais alto porque elas possuem nomes mais claros e oferecem variantes padronizadas. Entretanto, binascii é útil quando você precisa de controle direto, quer evitar conversões extras, precisa capturar binascii.Error ou está implementando um protocolo que especifica exatamente uma dessas transformações.

Antes de continuar, vale revisar a diferença entre strings no Python e dados binários. Uma str representa texto Unicode; bytes representa octetos. Converter entre os dois exige um encoding explícito, normalmente UTF-8.

Hexadecimal com hexlify e unhexlify

A representação hexadecimal é excelente para logs técnicos, inspeção de protocolos, IDs binários e comparação visual de bytes. Cada byte vira dois dígitos hexadecimais, então o resultado possui o dobro do tamanho da 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() é um alias de hexlify(), enquanto a2b_hex() é um alias de unhexlify(). Para código moderno e legível, os nomes hexlify e unhexlify costumam ser mais claros.

Também é possível inserir separadores:

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

Para tarefas simples, bytes.hex() retorna uma str, e bytes.fromhex() aceita espaços entre grupos. unhexlify() é mais rigoroso: a entrada precisa possuir quantidade par de dígitos válidos. Essa rigidez é útil ao validar um campo de protocolo.

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

Base64 de baixo nível

b2a_base64() transforma bytes em Base64. Por padrão, adiciona uma quebra de linha no final; use newline=False quando o valor será armazenado em JSON, banco de dados ou cabeçalho.

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

assert decoded == payload
print(encoded)

Base64 não criptografa nada. Qualquer pessoa pode decodificar o conteúdo. Ele serve apenas para transportar bytes por canais textuais. Para uma visão mais ampla, leia o guia de Base64 no Python.

Validação estrita de Base64

Ao receber dados externos, o modo tolerante pode ignorar caracteres fora do alfabeto. Isso é conveniente para formatos com quebras de linha, mas pode esconder entrada malformada. Desde Python 3.11, a2b_base64() oferece 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"))

O modo estrito rejeita caracteres externos ao alfabeto, padding excessivo, dados depois do padding e valores que começam incorretamente com =. Mesmo assim, aplique um limite de tamanho antes da decodificação. Uma entrada textual relativamente pequena pode produzir muitos bytes e consumir memória desnecessariamente.

Quoted-printable e cabeçalhos de e-mail

Quoted-printable mantém grande parte do texto ASCII legível e representa outros bytes com sequências como =C3=A7. É comum em mensagens MIME.

texto = "ação e informação".encode("utf-8")
encoded = binascii.b2a_qp(texto)
decoded = binascii.a2b_qp(encoded)

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

Os parâmetros header, quotetabs e istext mudam a interpretação de espaços, tabs e quebras de linha. Para e-mails completos, use o pacote email, que lida com MIME, cabeçalhos e políticas corretamente. binascii é apropriado quando você já conhece o formato exato do campo.

CRC-32 para detectar corrupção acidental

crc32() calcula um checksum de 32 bits compatível com o usado em arquivos ZIP. Ele é útil para detectar alterações acidentais durante armazenamento ou transmissão.

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

value = crc32_file(Path("dados.bin"))
print(f"{value:08x}")

O processamento em blocos evita carregar arquivos grandes inteiros na memória. Esse padrão combina bem com o guia sobre arquivos grandes no Python.

CRC não é adequado para senhas, assinaturas, tokens ou verificação contra adulteração maliciosa. Um atacante pode modificar os dados e recalcular o CRC. Para integridade criptográfica, use hashlib ou HMAC. Para armazenamento de senhas, use algoritmos específicos e consulte o artigo sobre hash seguro de senhas.

CRC-HQX e protocolos legados

crc_hqx() implementa CRC-CCITT de 16 bits. Ele aparece em formatos e dispositivos legados. A função exige um valor inicial definido pelo protocolo:

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

Não escolha o valor inicial por intuição. Consulte a especificação do equipamento ou protocolo, porque implementações que usam o mesmo polinômio podem divergir no valor inicial, reflexão dos bits e XOR final.

Processamento incremental e buffers

As funções recebem objetos bytes-like, incluindo bytes, bytearray e muitos objetos que implementam o protocolo de buffer. Isso permite trabalhar sem criar cópias extras em alguns fluxos.

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

Para decodificadores em streaming, lembre que um bloco pode terminar no meio de uma unidade codificada. binascii.Incomplete representa dados incompletos em algumas operações. Mantenha a sobra para o próximo bloco em vez de tratá-la imediatamente como corrupção.

Tratamento seguro de erros

Dados externos precisam ser considerados não confiáveis. Um fluxo robusto deve limitar o tamanho, validar o tipo, escolher uma função compatível com o formato esperado e transformar erros internos em mensagens úteis sem expor conteúdo sensível.

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

Evite registrar tokens, credenciais ou payloads completos em logs. Quando necessário, registre apenas tamanho, tipo da falha e um identificador de correlação. O guia de logging no Python ajuda a estruturar esse diagnóstico.

binascii ou módulos de nível mais alto?

Use base64 para Base16, Base32, Base64, Base85 e variantes URL-safe. Use quopri ou email para quoted-printable e MIME. Use métodos como bytes.hex() quando deseja uma string simples. Escolha binascii quando precisa das primitivas de baixo nível, de validação estrita, de CRC ou de integração com buffers.

Boas práticas

Defina explicitamente se a função recebe texto ou bytes. Valide limites antes de converter. Use o modo estrito para campos Base64 controlados. Diferencie checksums de hashes criptográficos. Processe arquivos em blocos. Capture binascii.Error perto da fronteira de entrada e converta a falha em um erro de domínio compreensível.

Conclusão

binascii é pequeno, rápido e muito útil quando você precisa enxergar os detalhes das conversões binárias. Ele oferece hexadecimal rigoroso, Base64 de baixo nível, quoted-printable, uuencode e CRCs. O ponto principal é escolher a abstração correta: use wrappers de alto nível no código cotidiano e recorra ao módulo quando precisar de controle, desempenho ou validação específica.

Consulte também a documentação oficial de binascii e o RFC 4648, que define as codificações Base16, Base32 e Base64.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    A person reads 'Python for Unix and Linux System Administration' indoors.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    codecs no Python: domine encodings

    Aprenda codecs no Python para trabalhar com encodings, handlers de erro, BOM, streams incrementais e migrar codecs.open para open.

    Ler mais

    Tempo de leitura: 7 minutos
    18/08/2026
    A person reads 'Python for Unix and Linux System Administration' indoors.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    base64 no Python: codifique dados

    Aprenda base64 no Python para codificar bytes, usar Base64 URL-safe, validar padding, aplicar limites e diferenciar encoding de criptografia.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    Detailed shot of a Jungle Carpet Python (Morelia spilota cheynei) in its natural habitat.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    urllib.parse no Python: manipule URLs

    Aprenda urllib.parse no Python para decompor URLs, criar queries, codificar componentes e evitar riscos com urljoin, redirects e SSRF.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    A person typing on a laptop with a Python programming book visible, capturing technology and learning.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ipaddress no Python: redes IPv4 e IPv6

    Aprenda ipaddress no Python para validar IPv4 e IPv6, calcular redes CIDR, dividir sub-redes e criar políticas de acesso seguras.

    Ler mais

    Tempo de leitura: 6 minutos
    18/08/2026
    A vibrant collection of blue sewing threads arranged with hands on a white background.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    queue no Python: coordene threads

    Aprenda queue no Python para coordenar threads com FIFO, prioridade, backpressure, task_done, join, retries e shutdown seguro.

    Ler mais

    Tempo de leitura: 5 minutos
    17/08/2026
    A male software engineer working on code in a modern office setting.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    struct no Python: trabalhe com binário

    Aprenda struct no Python para empacotar dados binários, controlar endianness, usar buffers e validar protocolos e arquivos externos.

    Ler mais

    Tempo de leitura: 5 minutos
    17/08/2026