如何将 4 个字节的二进制数据解包为 3 个字节和 1 个字节的值?
How to unpack 4 bytes of binary data as 3 byte and 1 byte values?
我有 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
可用于删除最后(最高)字节。)
是否有更优雅的方式来解压这些值?
这是一个合理的方式。另一种方式(不涉及备份)是
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
@hobbs 有一个很好的答案。我只是想提一下,您也可以在这种情况下使用 Numeric#divmod
:
ab, = data.unpack('L>')
a, b = ab.divmod(2**8)
或者只是:
a, b = data.unpack('L>')[0].divmod(2**8)
我有 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
可用于删除最后(最高)字节。)
是否有更优雅的方式来解压这些值?
这是一个合理的方式。另一种方式(不涉及备份)是
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
@hobbs 有一个很好的答案。我只是想提一下,您也可以在这种情况下使用 Numeric#divmod
:
ab, = data.unpack('L>')
a, b = ab.divmod(2**8)
或者只是:
a, b = data.unpack('L>')[0].divmod(2**8)