bitstruct
This module performs conversions between Python values and C bit field structs represented as Python byte strings. It offers an interface similar to Python's built-in `struct` module but operates at the bit level. The current version is 8.22.1, and it maintains an active release cadence with recent updates.
Warnings
- gotcha The C-backed implementations (`bitstruct.c` and `cbitstruct`) have limitations compared to the pure Python version. Integers and booleans are limited to 64 bits, and 'text' and 'raw' types must be multiples of 8 bits. `bitstruct.c` also lacks support for bit endianness, byte order, and `byteswap()` is restricted to 1, 2, 4, or 8 byte swaps.
- gotcha The `dict` API (e.g., `pack_dict`, `unpack_dict`) can be marginally slower than the traditional tuple-based API. The overhead of dictionary lookups and hashing can significantly increase packing/unpacking duration for performance-critical applications.
- gotcha The pure Python implementation is used by default even if `bitstruct.c` is available. To leverage the faster C implementation, you *must* explicitly import it, typically as `import bitstruct.c as bitstruct` or `import cbitstruct as bitstruct` (if `cbitstruct` is installed).
Install
-
pip install bitstruct
Imports
- pack
from bitstruct import pack, unpack, calcsize
- compile
import bitstruct compiled_format = bitstruct.compile('u8') - C-backed implementation
import bitstruct.c as bitstruct
- External C-backed implementation
import cbitstruct as bitstruct
Quickstart
from bitstruct import pack, unpack, calcsize
# Define a format string: u1 (1-bit unsigned), u3 (3-bit unsigned), u4 (4-bit unsigned), s16 (16-bit signed)
fmt = 'u1u3u4s16'
# Pack values into a byte string
packed_data = pack(fmt, 1, 2, 3, -4)
print(f"Packed data: {packed_data}")
# Expected: b'\xa3\xff\xfc'
# Unpack values from the byte string
unpacked_values = unpack(fmt, packed_data)
print(f"Unpacked values: {unpacked_values}")
# Expected: (1, 2, 3, -4)
# Calculate the total number of bits required for the format
size_in_bits = calcsize(fmt)
print(f"Size in bits: {size_in_bits}")
# Expected: 24 (bits)
# Using a compiled format for efficiency
import bitstruct
cf = bitstruct.compile(fmt)
compiled_packed = cf.pack(1, 2, 3, -4)
compiled_unpacked = cf.unpack(compiled_packed)
print(f"Compiled format packed: {compiled_packed}")
print(f"Compiled format unpacked: {compiled_unpacked}")