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.







