我有一堆二进制数据(视频游戏保存文件的内容,当它发生时),其中一部分数据包含little-endian 和 big-endian整数值。天真的,没有读过很多文档,我试着以这种方式解压缩......
struct.unpack(
'3sB<H<H<H<H4s<I<I32s>IbBbBbBbB12s20sBB4s',
string_data
)
...当然我收到了这个神秘的错误信息:
struct.error: bad char in struct format
问题是struct.unpack
格式字符串不希望单个字段标记为字节序。这里实际上正确的格式字符串就像是
struct.unpack(
'<3sBHHHH4sII32sIbBbBbBbB12s20sBB4s',
string_data
)
除了这将翻转第三个I
字段的字节顺序(将其解析为little-endian,当我真的想将其解析为big-endian时)。
是否有一个简单的和/或&#34; Pythonic&#34;解决我的问题?我已经想到了三种可能的解决方案,但它们都没有特别优雅。如果没有更好的想法,我可能会选择3号:
我可以提取子字符串并单独解析它:
(my.f1, my.f2, ...) = struct.unpack('<3sBHHHH4sII32sIbBbBbBbB12s20sBB4s', string_data)
my.f11 = struct.unpack('>I', string_data[56:60])
事后我可以flip the bits in the field:
(my.f1, my.f2, ...) = struct.unpack('<3sBHHHH4sII32sIbBbBbBbB12s20sBB4s', string_data)
my.f11 = swap32(my.f11)
我可以改变我的下游代码,期望这个字段的表示方式不同 - 它实际上是一个位掩码,而不是算术整数,所以它也不会 > 我很难翻转我用过的所有位掩码;但这些位掩码的big-endian版本比little-endian版本更具有记忆性。
答案 0 :(得分:0)
聚会晚了一点,但是我也遇到了同样的问题。我使用自定义numpy dtype解决了该问题,该类型允许混合具有不同字节序的元素(请参见https://numpy.org/doc/stable/reference/generated/numpy.dtype.html):
t=np.dtype('>u4,<u4') # Compound type with two 4-byte unsigned int with different byte order
a=np.zeros(shape=1, dtype=t) # Create an array of length one with above type
a[0][0]=1 # Assign first uint
a[0][1]=1 # Assign second uint
bytes=a.tobytes() # bytes should be b'\x01\x00\x00\x00\x00\x00\x00\x01'
b=np.frombuffer(buf, dtype=t) # should yield array[(1,1)]
c=np.frombuffer(buf, dtype=np.uint32) # yields array([ 1, 16777216]