I need the Python analog for this Perl string:
unpack("nNccH*", string_val)
I need the nNccH*
- data format in Python format characters.
In Perl it unpack binary data to five variables:
But I can't do it in Python
More:
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 multithreading Python server that was written in Perl...
Method : Using format() + * operator + values() The combination of above functions can be used to solve this problem. In this, we use format to map required value with braces in string. The * operator is used to unpack and assign. The values are extracted using values().
unpack() This function converts the strings of binary representations to their original form according to the specified format.
struct. calcsize('P') calculates the number of bytes required to store a single pointer -- returning 4 on a 32-bit system and 8 on a 64-bit system.
Python offers several data types that you can use to implement records, structs, and data transfer objects.
The Perl format "nNcc"
is equivalent to the Python format "!HLbb"
.
There is no direct equivalent in Python for Perl's "H*"
.
There are two problems.
struct.unpack
does not accept the wildcard character, *
struct.unpack
does not "hexlify" data stringsThe first problem can be worked-around using a helper function like unpack
.
The second problem can be solved using 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 tested on data produced by this Perl script:
$line = pack("nNccH*", 1, 2, 10, 4, '1fba');
print "$line";
The Python script yields
[1, 2, 10, 4, '1fba']
The equivalent Python function you're looking for is struct.unpack
. Documentation of the format string is here: http://docs.python.org/library/struct.html
You will have a better chance of getting help if you actually explain what kind of unpacking you need. Not everyone knows Perl.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With