如何将 4 字节的二进制数据解包为 3 字节和 1 字节的值?
Posted
技术标签:
【中文标题】如何将 4 字节的二进制数据解包为 3 字节和 1 字节的值?【英文标题】:How to unpack 4 bytes of binary data as 3 byte and 1 byte values? 【发布时间】:2016-02-11 02:36:58 【问题描述】:我有 4 个字节的二进制数据(big-endian)要解压。如果它包含两个 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
(如果数据是 little-endian,则可以使用 a &= 0xFFFFFF
删除最后一个(最高)字节。)
有没有更优雅的方式来解压这些值?
【问题讨论】:
【参考方案1】:这是一种合理的方式。另一种方式(不涉及备份)是
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)
【讨论】:
以上是关于如何将 4 字节的二进制数据解包为 3 字节和 1 字节的值?的主要内容,如果未能解决你的问题,请参考以下文章