用struct.pack将字节数组中的字节打包为4字节整数
我正在尝试把一个Python的字节数组(bytearray)打包成一个4字节的有符号整数,使用的是struct.pack这个工具。可是,pack需要的是字符串,所以我在网上查了一下,发现我需要把字节数组解码成字符串。我以为ascii编码可以用,因为一个ascii字符正好是一个字节长。
可惜的是,ascii不支持我大于127的值,所以我想用替换的方法...
但是当我这样做的时候,解码后得到的是一种unicode类型的对象,现在我的每个字节变成了4个字符的字符串...
这看起来有点荒谬,我觉得我漏掉了什么明显的东西(顺便说一下,我才学Python大约两周)
这是我想要做的事情...
val = long(-5)
s = bytearray(pack("<i", val))
s.pop() # pop off msb
# write it out the way we want to then read it in the way the code does
fout = open("test.bat", "wb")
fout.write(s)
fout.close()
fin = open("test.bat", "rb")
inBytes = bytearray(fin.read(3))
# extend sign bit
if (inBytes[2] & 0x80):
inBytes.append(0xff)
else:
inBytes.append(0x00)
nb = inBytes.decode('ascii', 'replace')
# ERROR:root:after decode, len: 4 type: <type 'unicode'>
logging.error("after decode, len: {0} type: {1}".format(len(nb), type(nb)))
# struct.error: unpack requires a string argument of length 4
inInt32 = unpack('<i', inBytes.decode('ascii', 'replace'))[0]
fin.close()
2 个回答
1
你只需要把 inBytes
转换回 str
类型就可以了:
>>> inint = struct.unpack('<i', str(inBytes))
>>> inint
(-5,)
1
当你以二进制模式从文件中读取数据时,你会得到一个可以直接用 struct.unpack
来处理的对象。
创建输入数据:
>>> import struct
>>> f = open('foo.bin', 'wb')
>>> f.write(struct.pack('<i', -5)[:3])
3
>>> f.close()
Python 2.x .. 这时候得到的是一个 str
对象。
>>> f = open('foo.bin', 'rb')
>>> raw = f.read()
>>> f.close()
>>> print "received", type(raw), repr(raw)
received <type 'str'> '\xfb\xff\xff'
>>> if raw[2] >= '\x80':
... raw += '\xff'
... else:
... raw += '\x00'
...
>>> print "extended", type(raw), repr(raw)
extended <type 'str'> '\xfb\xff\xff\xff'
>>> number = struct.unpack('<i', raw)[0]
>>> print "number", number
number -5
>>>
Python 3.x ... 这时候得到的是一个 bytes
对象。
>>> f = open('foo.bin', 'rb')
>>> raw = f.read()
>>> f.close()
>>> print("received", type(raw), repr(raw))
received <class 'bytes'> b'\xfb\xff\xff'
>>> if raw[2] & 0x80:
... raw += b'\xff'
... else:
... raw += b'\x00'
...
>>> print("extended", type(raw), repr(raw))
extended <class 'bytes'> b'\xfb\xff\xff\xff'
>>> number = struct.unpack('<i', raw)[0]
>>> print("number", number)
number -5
>>>