Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python struct: a fixed-endian receipt record with exact byte length

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

Struct packs and unpacks values according to a declared binary layout, including byte order and field widths.

Download Python source kit

Operation contract

The receipt wire format is exactly nine bytes: a one-byte version, a four-byte identifier and a four-byte amount, all in network byte order. The encoder rejects Boolean values and unsigned overflow before packing. The decoder rejects truncation and trailing bytes before unpacking, then rejects an unsupported version. A file containing several records would need framing and a count or total-byte bound rather than this single-record function.

Failure and ownership boundary

Native alignment depends on the host ABI. The explicit ! prefix avoids silently changing the protocol across machines. The record has no signature or checksum; successfully unpacking bytes does not establish their origin. Python memoryview: shared buffers and explicit release, Python array: fixed-width numeric storage is not a portable wire encoding and Python HMAC envelopes: authenticate exact bytes and separate replay policy cover different ownership and trust boundaries.

Working program

python
import struct

RECEIPT = struct.Struct("!BII")
def encode_receipt(receipt_id, amount):
    if any(type(value) is not int or not 0 <= value <= 0xFFFFFFFF
           for value in (receipt_id, amount)):
        raise ValueError("unsigned exact integers required")
    return RECEIPT.pack(1, receipt_id, amount)

def decode_receipt(payload):
    if type(payload) is not bytes or len(payload) != RECEIPT.size:
        raise ValueError("exact record bytes required")
    version, receipt_id, amount = RECEIPT.unpack(payload)
    if version != 1:
        raise ValueError("unsupported version")
    return receipt_id, amount

payload = encode_receipt(41, 125)
print("bytes:", payload.hex())
print("record:", decode_receipt(payload))
for invalid in (payload[:-1], payload + b"x", bytes([2]) + payload[1:]):
    try:
        decode_receipt(invalid)
    except ValueError:
        print("record rejected")

Output

Output
bytes: 01000000290000007d
record: (41, 125)
record rejected
record rejected
record rejected

Costs and limits

The format has fixed time and space costs because the field count and widths are fixed. A bytes argument can already be large before this function receives it; bound reception at the transport too. Rejecting an invalid version does not reverse bytes consumed by an earlier reader.

Common Mistakes

  • Never use implicit native alignment for a portable wire contract.
  • Do not accept a valid prefix while ignoring unexplained trailing bytes.

Connected lessons

Python strings and bytes: reject decoding errors before parsing records, Python strict Base64: reject alternate spellings before decoding a record, Python HMAC envelopes: authenticate exact bytes and separate replay policy.

Follow the ownership and update boundary

Python socket recv: assemble a bounded frame across partial reads.

python
binary-records
Storage details