tomasz
tomasz

Reputation: 333

How do you pack three bytes into a python struct?

Given a hex value of 0x183C6 I'd like to write out its corresponding byte value using exactly 3 bytes. I know that struct would do this to 4 bytes but my constraints are to 3 bytes.

So

>>> val = 0x183c6
>>> struct.pack('>L', val)
'\x00\x01\x83\xc6'

Is great but I just want:

'\x01\x83\xc6'

I could post process and strip it after the fact, I could break it up and put each individual byte into a bytearray(), or perhaps do some bit shifting but I wonder if there is a easier way of doing it within struct without post processing.

Upvotes: 2

Views: 6588

Answers (2)

chepner
chepner

Reputation: 532303

You can split the value into its high byte and low 16-bit word with divmod:

>>> struct.pack(">BH", *divmod(0x183c6, 1<<16))
'\x01\x83\xc6'

To unpack,

>>> struct.unpack(">I", '\x00' + '\x01\x83\xc6')

Upvotes: 4

Mark Nunberg
Mark Nunberg

Reputation: 3701

You can't really do that, since that's not how structs work. If you absolutely know that the value will never exceed 3 bytes, you can use big-endian encoding for both packing and unpacking:

>>> val = 0x183c6
>>> packed = struct.pack('>L', val)[1:]
>>> packed
'\x01\x83\xc6'
>>> '{0:x}'.format(struct.unpack('>L', '\x00' + packed)[0])
'183c6'

Note that the packed value will pretty much be useless for passing to other C functions, or similar.

Upvotes: 1

Related Questions