How to unpack 4 bytes of binary data as 3 byte and 1 byte values?

I have 4 bytes of binary data (big-endian) that I want to unpack. If it contained two 2-byte unsigned integer values, this would be straightforward:

a, b = data.unpack("C>C>")

But what if the data contains a 3-byte value (a) followed by a 1-byte value (b)? The unpack method doesn't seem to be able to handle formats other than 8-, 16-, 32-, and 64-bit integers. This is what I came up with:

a, b = data.unpack("L>XC")   # "L>": unpack a 32-bit unsigned int (big-endian)
                             # "X":  rewind (skip back) one byte
                             # "C":  unpack an 8-bit unsigned int
a >>= 8                      # drop the last (lowest) byte from a

(If the data were little-endian, a &= 0xFFFFFF could be used to drop the last (highest) byte instead.)

Is there a more elegant way to unpack these values?


That's a reasonable way. Another way (that doesn't involve backing up) would be

a, b, c = data.unpack("S>CC") # C doesn't have endianness
ab = a << 8 + b

Since your values are unsigned, you don't need to worry about sign extension when sticking them together.

And for completeness, you could also go in the opposite direction — unpack a single 32-bit int and split it up using bit operations.

ab, = data.unpack("L>")
a, b = ab >> 8, ab & 0xFF

@hobbs has a good answer. I just wanted to mention that you can also use Numeric#divmod in this case:

ab, = data.unpack('L>')
a, b = ab.divmod(2**8)

Or just:

a, b = data.unpack('L>')[0].divmod(2**8)

Need Your Help

installation wxPython on Ubuntu 11.10

python ubuntu installation wxpython

hope somebody helps me to install wxPython.

Replacing recorded values with Data file - Data driven testing

visual-studio-2013 coded-ui-tests data-driven-tests data-driven

I have recorded a simple Coded UI test from visual Studio 2013. What it does is;