如何将4字节的二进制数据拆分为3字节和1字节的值?

4

我有4个字节的二进制数据(大端序),需要解包。如果它包含了两个2字节无符号整数值,那么这将是很简单的:

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

但是如果数据包含一个3字节的值(a),后面跟着一个1字节的值(b)呢?unpack方法似乎不能处理除8、16、32和64位整数格式以外的其他格式。这是我想出来的:

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

如果数据采用小端编码,可以使用a&=0xFFFFFF来丢弃最后(最高)一个字节。是否有更加优雅的方法来解包这些值?
2个回答

4
这是一个合理的方法。另一种方式(不涉及备份)是:
a, b, c = data.unpack("S>CC") # C doesn't have endianness
ab = a << 8 + b

由于您的值是无符号的,因此在将它们粘合在一起时不必担心符号扩展的问题。

为了完整起见,您还可以反过来操作 - 使用位运算解压缩一个单独的32位int并将其分割。

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

2

@hobbs有一个很好的答案。我只想提一下,在这种情况下,你也可以使用Numeric#divmod

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接