Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python struct.pack(): pack multiple datas in a list or a tuple

Say i have a list or a tuple containing numbers of type long long,

x = [12974658, 638364, 53637, 63738363]

If want to struct.pack them individually, i have to use

struct.pack('<Q', 12974658)

or if i want to do it as multiple, then i have to explicitly mention it like this

struct.pack('<4Q', 12974658, 638364, 53637, 63738363)

But, how can i insert items in a list or tuple inside a struct.pack statement. I tried using for loop like this.

struct.pack('<4Q', ','.join(i for i in x))

got error saying expected string, int found, so i converted the list containing type int into str, now it gets much more complicated to pack them. Because the whole list gets converted into a string( like a single sentence).

As of now im doing some thing like

binary_data = ''
x = [12974658, 638364, 53637, 63738363]
for i in x:
    binary_data += struct.pack('<Q', i)

And i unpack them like

struct.unpack('<4Q', binary_data)

My question: is there a better way around, like can i directly point a list or tuple inside the struct.pack statement, or probably a one liner ?

like image 425
arvindh Avatar asked Jan 14 '16 16:01

arvindh


1 Answers

You can splat, I'm sorry "unpack the argument list":

>>> struct.pack("<4Q", *[1,2,3,4])
'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'

If the length of the list is dynamic, you can of course build the format string at runtime too:

>>> x = [1, 2] # This could be any list of integers, of course.
>>> struct.pack("<%uQ" % len(x), *x)
'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00'
like image 57
unwind Avatar answered Oct 13 '22 19:10

unwind