Reputation: 333
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
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
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