python mengemas 4 byte integer dengan byte di bytearray struct.pack

Saya mencoba mengemas konten python bytearray ke dalam integer bertanda 4byte menggunakan struct.pack. Sayangnya, paket menginginkan sebuah string, jadi setelah beberapa googling saya pikir saya perlu memecahkan kode bytearray saya menjadi sebuah string. Saya pikir maksud ascii karena karakter ascii panjangnya satu byte. Sayangnya, ascii tidak mau mendukung nilai saya > 127, jadi saya pikir saya akan menggunakan replace...

tetapi ketika saya melakukan dekode ini mengembalikan objek bertipe unicode dan sekarang setiap byte saya adalah string 4 karakter...

Ini sepertinya agak konyol, saya melewatkan sesuatu yang jelas (ps saya telah menggunakan python selama sekitar dua minggu)

inilah yang saya coba lakukan...

    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 sumber


Jawaban (2)


Yang Anda butuhkan hanyalah mengembalikan inBytes ke str:

>>> inint = struct.unpack('<i', str(inBytes))
>>> inint
(-5,)
person Santa    schedule 20.05.2011
comment
-1 Untuk Python 2.x, sebaiknya tetap menggunakan str; str -› bytearray -› str membingungkan. Juga tidak ada konsep seperti cast dengan Python. - person John Machin; 21.05.2011

Saat Anda membaca file dalam mode biner, Anda mendapatkan objek yang dapat langsung digunakan dengan struct.unpack.

Membuat data masukan:

>>> import struct
>>> f = open('foo.bin', 'wb')
>>> f.write(struct.pack('<i', -5)[:3])
3
>>> f.close()

Python 2.x .. itu adalah objek 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 ... itu adalah objek 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