Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting list of integers into a binary "string" in python

I have a list of numbers that i would like to send out onto a socket connection as binary data.

As an example, i start off with the following list:

data = [2,25,0,0,ALPHA,0,23,18,188]

In the above list, ALPHA can be any value between 1 and 999. Initially, I was converting this into a string using

 hexdata = ''.join([chr(item) for item in data])

So if ALPHA is 101, this would return the following string:

>>> data = [2,25,0,0,101,0,23,18,188]
>>> hexdata = ''.join([chr(item) for item in data])
>>> hexdata
'\x02\x19\x00\x00e\x00\x17\x12\xbc'

This works just fine and '\x02\x19\x00\x00e\x00\x17\x12\xbc' is the string that i need to send out.

However, this does not work for values of ALPHA that are over 255 because its out of range of the chr statement. If for example ALPHA were 999, then i would like to get the following string:

data = [2,25,0,0,999,0,23,18,188]
hexdata = '\x02\x19\x00\x03\xed\x00\x17\x12\xbc'

Ive been looking at the documentation on the struct.pack() but cannot see how that could be used to acheive the above string. ALPHA is the only variable in the list.

Any help would be greatly appreciated.

EDIT 1

What behavior do you want? Anything between 256 and 65535 takes 2 bytes to represent. Do you want to unpack it on the other side? Please update the post with your intent. – gahooa 1 min ago

Thats correct, since 999 is over the 256 threshold, its represented by two bytes:

data = [2,25,0,0,999,0,23,18,188]

hexdata = '\x02\x19\x00**\x03\xed**\x00\x17\x12\xbc'

Does this make sense?

As far as unpacking is concerned, im only sending this data out onto the socket, I will be receiving data but thats taken care of already.

EDIT 2

The string i send out is always fixed length. For simplicity, I think its better to represent the list as follows:

ALPHA = 101

data = [25,alpha1,alpha2,1]
hexdata = '\x19\x00e\x01'


ALPHA = 301

data = [25,alpha1,alpha2,1]
hexdata = 'x19\x01\x2d\x01'

as you can see in the hexdata string, this then becomes: \x01\x2d\

If ALPHA < 256, alpha1 = 0.

like image 415
mozami Avatar asked Dec 03 '22 07:12

mozami


2 Answers

You want to send a single byte for ALPHA if it's < 256, but two bytes if >= 256? This seems weird -- how is the receiver going to know which is the case...???

But, if this IS what you want, then

x = struct.pack(4*'B' + 'HB'[ALPHA<256] + 4*'B', *data)

is one way to achieve this.

like image 126
Alex Martelli Avatar answered Dec 19 '22 06:12

Alex Martelli


If you know the data and ALPHA position beforehand, it would be best to use struct.pack with a big endian short for that position and omit the 0 that might be overwritten:

def output(ALPHA):
    data = [2,25,0,ALPHA,0,23,18,188]
    format = ">BBBHBBBB"
    return struct.pack(format, *data)
output(101) # result: '\x02\x19\x00\x00e\x00\x17\x12\xbc'
output(999) # result: '\x02\x19\x00\x03\xe7\x00\x17\x12\xbc'
like image 36
Ants Aasma Avatar answered Dec 19 '22 05:12

Ants Aasma