python pack จำนวนเต็ม 4 ไบต์พร้อมไบต์ใน bytearray struct.pack

ฉันกำลังพยายามแพ็คเนื้อหาของ python bytearray ลงในจำนวนเต็มที่ลงนามขนาด 4 ไบต์โดยใช้ struct.pack น่าเสียดายที่ pack ต้องการสตริง ดังนั้นหลังจากใช้ googling ฉันคิดว่าฉันต้องถอดรหัส bytearray เป็นสตริง ฉันคิดว่า ascii มีความหมายเพราะว่าอักขระ ascii มีความยาวหนึ่งไบต์ น่าเสียดายที่ ascii ไม่ต้องการสนับสนุนค่าของฉัน > 127 ดังนั้นฉันคิดว่าฉันจะใช้การแทนที่...

แต่เมื่อฉันทำการถอดรหัสนี้ส่งคืนออบเจ็กต์ประเภทยูนิโค้ดและตอนนี้แต่ละไบต์ของฉันเป็นสตริงอักขระ 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()

person mike    schedule 20.05.2011    source แหล่งที่มา


คำตอบ (2)


สิ่งที่คุณต้องมีคือส่ง inBytes กลับไปที่ str:

>>> inint = struct.unpack('<i', str(inBytes))
>>> inint
(-5,)
person Santa    schedule 20.05.2011
comment
-1 สำหรับ Python 2.x ควรใช้ str ดีที่สุด str -> bytearray -> str กำลังสับสน นอกจากนี้ยังไม่มีแนวคิดแบบหล่อใน Python - person John Machin; 21.05.2011

เมื่อคุณอ่านจากไฟล์ในโหมดไบนารี คุณจะได้รับออบเจ็กต์ที่สามารถใช้งานได้ทันทีด้วย 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
>>>
person John Machin    schedule 20.05.2011