Unzip format characters in Python

I need a Python analog for this Perl line:

unpack("nNccH*", string_val) 

I need the nNccH* format - data in Python format characters.

In Perl, it decompresses binary data into five variables:

  • 16-bit value in "network" (big-endian)
  • 32-bit value in "network" (big-endian)
  • Signed char (8-bit integer) value
  • Signed char (8-bit integer) value
  • Hexadecimal string, high first piece

But I can not do it in Python

More details:

 bstring = '' while DataByte = client[0].recv(1): bstring += DataByte print len(bstring) if len(bstring): a, b, c, d, e = unpack("nNccH*", bstring) 

I never wrote in Perl or Python, but my current task is to write a multi-threaded Python server written in Perl ...

+4
source share
2 answers

The Perl format "nNcc" equivalent to the Python format "!HLbb" . In Python there is no direct equivalent for Perl "H*" .

There are two problems.

  • Python struct.unpack does not accept wildcard, *
  • Python struct.unpack does not perform "hexlify" data rows

The first problem can be solved with an auxiliary function like unpack .

The second problem can be solved with binascii.hexlify :

 import struct import binascii def unpack(fmt, data): """ Return struct.unpack(fmt, data) with the optional single * in fmt replaced with the appropriate number, given the length of data. """ # http://stackoverflow.com/a/7867892/190597 try: return struct.unpack(fmt, data) except struct.error: flen = struct.calcsize(fmt.replace('*', '')) alen = len(data) idx = fmt.find('*') before_char = fmt[idx-1] n = (alen-flen)//struct.calcsize(before_char)+1 fmt = ''.join((fmt[:idx-1], str(n), before_char, fmt[idx+1:])) return struct.unpack(fmt, data) data = open('data').read() x = list(unpack("!HLbbs*", data)) # x[-1].encode('hex') works in Python 2, but not in Python 3 x[-1] = binascii.hexlify(x[-1]) print(x) 

When testing the data received by this Perl script:

 $line = pack("nNccH*", 1, 2, 10, 4, '1fba'); print "$line"; 

Python script gives

 [1, 2, 10, 4, '1fba'] 
+7
source

The equivalent Python function you are looking for is struct.unpack . The format string documentation is here: http://docs.python.org/library/struct.html

You will have a better chance of getting help if you really explain what kind of unpacking you need. Not everyone knows Perl.

+6
source

Source: https://habr.com/ru/post/1395221/


All Articles