Guia de Uso do Módulo struct em Python

O módulo struct é uma ferramenta nativa do Python que facilita a conversão entre tipos de dados Python e estruturas binárias. Em comunicações via socket, os dados são frequentemente transmitidos como fluxos binários. O struct permite empacotar tipos específicos em bytes de formato fixo para envio pela rede, e também oferece a funcionalidade reversa de desempacotamento para reconstruir os dados originais no destino.

Como o struct Funciona

O módulo transforma números de qualquer tamanho em uma sequência de bytes de comprimento fixo (escolhido pelo usuário). Isso lembra funções hash, onde a saída tem tamanho constante independentemente da entrada, mas difere porque hashes são irreversíveis e aceitam dados como texto, strings, etc. O struct, por outro lado, permite reverter o processo e obter os valores originais.

Atenção: O módulo trabalha apenas com números; não converte strings ou outros objetos diretamente.

Operações Básicas: pack e unpack

Exemplo de uso correto (a tabela de formatos está mais adiante):

import struct

# Empacotar um inteiro
data = struct.pack("i", 1234566)
print(data)          # b'\x86\xd6\x12\x00'
print(type(data))    # <class 'bytes'>

# Desempacotar usando o mesmo formato
original = struct.unpack("i", data)
print(original)       # (1234566,)
print(type(original)) # <class 'tuple'>
print(original[0])    # 1234566

Exemplo de erro ao passar tipo incorreto:

import struct
# Isso gera uma exceção: struct.error: required argument is not an integer
# res = struct.pack("i", "1231")

Erro ao usar formatos diferentes no empacotamento e desempacotamento:

import struct
res = struct.pack("i", 123)
# Isso causa erro: struct.error: unpack requires a buffer of 8 bytes
# res2 = struct.unpack("q", res)

Empacotando e desempacotanod múltiplos valores:

import struct

# Empacota três valores com formatos diferentes
packed = struct.pack("hiq", 12, 23, 451312)
print(packed)  # b'\x0c\x00\x00\x00\x17\x00\x00\x00\xf0\xe2\x06\x00\x00\x00\x00\x00'
print(type(packed))  # <class 'bytes'>

# Desempacota e atribui a variáveis
a, b, c = struct.unpack("hiq", packed)
print(a, b, c)  # 12 23 451312

Exemplo de erro ao desempacotar com número incorreto de valores:

# Supondo que escrevemos 5 números em um arquivo
with open("data.bin", "wb") as f:
    for i in range(5):
        f.write(struct.pack("i", i))

# Tentar ler e desempacotar com formato único causa erro
with open("data.bin", "rb") as f:
    data = f.read()
    # Isto falha: struct.error: unpack requires a buffer of 4 bytes
    # a, b, c, d, e = struct.unpack("i", data)

Aplicação em Comunicação Socket: Cabeçalhos de Tamanho Fixo

Você pode empacotar o comprimento de um cabeçalho JSON para enviar como prefixo em transmissões socket.

import struct
import json

header_info = {
    "header_name": "a.txt",
    "total_size": 22,
    "hash": "shawn"
}

header_json = json.dumps(header_info)
packed_len = struct.pack("i", len(header_json))

# No lado receptor, desempacota para obter o tamanho
length_received = struct.unpack("i", packed_len)
print(length_received)   # (60,)
print(length_received[0]) # 60

Tabela de Formatos e Tamanhos de Bytes

Caractere (Format) Tipo C Tipo Python Tamanho Padrão (bytes)
x byte de preenchimento sem valor
c char string de 1 caractere 1
b signed char inteiro 1
B unsigned char inteiro 1
? _Bool bool 1
h short inteiro 2
H unsigned short inteiro 2
i int inteiro 4
I unsigned int inteiro 4
l long inteiro 4
L unsigned long inteiro 4
q long long inteiro 8
Q unsigned long long inteiro 8
f float float 4
d double float 8
s char[] string
p char[] string
P void* inteiro

Tags: Python struct pack unpack empacotamento binário

Publicado em 7-31 09:18