Search code examples
pythonbinarypack

struct.pack longer than its parts?


I want to unpack 6 values: 2 * UInt16, 1 * UInt32, 1 * UInt16, 2 * Int64

Adding the size in bytes up, I get 26.

But python seems to think it should be 32:

>>> a = struct.pack("H",0)
>>> len(a)
2 <-- correct
>>> a = struct.pack("L",0)
>>> len(a)
4 <-- correct
>>> a = struct.pack("q",0)
>>> len(a)
8 <-- correct
>>> a = struct.pack("HHLHqq",0,0,0,0,0,0)
>>> len(a)
32 < -- should be 2 + 2 + 4 + 2 + 8 + 8 = 26 
>>> a = struct.pack("HHLHq",0,0,0,0,0)
>>> len(a)
24 < -- should be 2 + 2 + 4 + 2 + 8 = 18
>>> a = struct.pack("HHLH",0,0,0,0)
>>> len(a)
10 <-- correct again

struct.unpack has the same problem and requires 32 byte to unpack "HHLHqq". However, in my application the data gets send from an external source and it's just 26 bytes.

I could unpack it one by one as a workaround, but there must be a way to disable this padding for sure?


Solution

  • According to: https://docs.python.org/2/library/struct.html

    No padding is added when using non-native size and alignment, e.g. with ‘<’, ‘>’, ‘=’, and ‘!’.

    So you have to just specify the endianness and the padding will be gone:

    >>> import struct
    >>> len(struct.pack("HHLHqq",0,0,0,0,0,0))
    40
    >>> len(struct.pack("<HHLHqq",0,0,0,0,0,0))
    26
    >>>