Python, Perl and PHP interoperability with pack and unpack
April 27th, 2009Perl has very powerful capabilities for dealing with structures. PHP’s support of those structures was based on Perl’s wisdom. Python went a different direction.
Perl pack/unpack definitions
PING_FORMAT => ‘(a4n2N2N/a*)@245’;
TASK_FORMAT => ‘a4NIN/a*a*’;
RETR_FORMAT => ‘a4N/a*N’;
ENCPAYLOAD_FORMAT => ‘Na*’;
PHP pack/unpack definitions
define(‘TASK_FORMAT’, ‘a4NINa*a*’);
define(“ENCPAYLOAD_FORMAT”,’Na*’);
For a communications package written in perl that communicates with 32 bit and 64 bit machines that may not share the same endian structure. The problem I’ve run into now is that Python does not support the Perl method, and, I don’t know why they didn’t at least offer some compatibility. pack and unpack give enormous power to communication systems between machines and their support of the perl methods allowed for reasonable interoperability between the two platforms.
Python on the other hand opted to not support some of the features, which was one issue, but, their requirement is that you cannot send variable length packets.
In Python, we’re able to replicate N, network endian Long by using !L:
>>> import struct
>>> print struct.unpack(‘!L’,’\0\0\1\0′);
(256,)
However, there is no method to support a variable length payload behind that value. We’re able to set a fixed length like 5s, but, this means that we’ve got to know the length of the payload being sent.
>>> print struct.unpack(‘!L5s’,’\0\0\1\0abcde’);
(256, ‘abcde’)
If we overstate the size of the field, Python is more than happy to tell us that the payload length doesn’t match the length of the data.
>>> print struct.unpack(‘!L8s’,’\0\0\1\0abcde’);
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
File “/usr/lib/python2.5/struct.py”, line 87, in unpack
return o.unpack(s)
struct.error: unpack requires a string argument of length 12
The cheeseshop/pypi seems to show no suitable alternative which brings up a quandry. For this particular solution, I’ll write a wrapper function to do the heavy lifting on the two unpack strings I need to deal with and then I’ll debate pulling the perl unpack/pack routines out of the perl source and wrapping it into an .egg, possibly for distribution.