Python:struct
lastmod 2024-07-10created 2024-04-054 edits
Interpret bytes as packed binary data
Byte Order, Size, and Alignment
By default, C types are represented in the machine's native format and byte order, and properly aligned by skipping pad bytes if necessary (according to the rules used by the C compiler). This behavior is chosen so that the bytes of a packed struct correspond exactly to the memory layout of the corresponding C struct. Whether to use native byte ordering and padding or standard formats depends on the application.
Alternatively, the first character of the format string can be used to indicate the byte order, size and alignment of the packed data, according to the following table:
| Character | Byte order | Size | Alignment |
| | native | native | native |
| | native | standard | none |
| | little-endian | standard | none |
| | big-endian | standard | none |
| | network (= big-endian) | standard | none |
If the first character is not one of these, '@' is assumed.
Format Characters
Format characters have the following meaning; the conversion between C and Python values should be obvious given their types. The ‘Standard size’ column refers to the size of the packed value in bytes when using standard size; that is, when the format string starts with one of '<', '>', '!' or '='. When using native size, the size of the packed value is platform-dependent.
| Format | C Type | Python type | Standard size | Notes |
| | pad byte | no value | - | (7) |
| | char | bytes of length 1 | 1 | - |
| | signed char | integer | 1 | (1), (2) |
| | unsigned char | integer | 1 | (2) |
| | _Bool | bool | 1 | (1) |
| | short | integer | 2 | (2) |
| | unsigned short | integer | 2 | (2) |
| | int | integer | 4 | (2) |
| | unsigned int | integer | 4 | (2) |
| | long | integer | 4 | (2) |
| | unsigned long | integer | 4 | (2) |
| | long long | integer | 8 | (2) |
| | unsigned long long | integer | 8 | (2) |
| | ssize_t | integer | - | (3) |
| | size_t | integer | - | (3) |
| | (6) | float | 2 | (4) |
| | float | float | 4 | (4) |
| | double | float | 8 | (4) |
| | char[] | bytes | - | (9) |
| | char[] | bytes | - | (8) |
| | void* | integer | - | (5) |
Serializing an Integer to Bytes
- Built-in Types — Python 3.12.4 documentation # int.to_bytes
- struct — Interpret bytes as packed binary data — Python 3.12.4 documentation # examples
data = 9999
serialized_data = data.to_bytes(4, "big", signed=False)
print(serialized_data.hex()) ## 0000270f
result = int.from_bytes(serialized_data, "big", signed=False)
print(result) ## 9999
Converting the code above to use Python:struct:
from struct import calcsize, pack, unpack
data = 9999
serialized_data = pack('>I', data)
print(serialized_data.hex()) ## 0000270f
unpacked_data = unpack('>I', serialized_data)
assert isinstance(unpacked_data, tuple)
assert len(unpacked_data) == 1
result = unpacked_data[0]
print(result) ## 9999
print(calcsize('>I')) ## 4