Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading 3 bytes as an integer

Tags:

python

How can I read 3 bytes as an integer?

Does struct module provide something like that?

I can read in 3 bytes and add an extra \x00 and then interpret it as a 4-byte integer, but that seems unnecessary.

like image 845
MxLDevs Avatar asked Apr 18 '12 19:04

MxLDevs


3 Answers

The struct module has no option for 3-byte integers, so I think your idea of appending '\x00' is the easiest way.

In [30]: import struct
In [38]: struct.pack('>3b',0,0,1)
Out[38]: '\x00\x00\x01'

In [39]: struct.unpack('>i','\x00'+'\x00\x00\x01')
Out[39]: (1,)
like image 145
unutbu Avatar answered Oct 02 '22 06:10

unutbu


I think from 3.2, int developed a new method .from_bytes, so you're able to use the following instead of struct.unpack:

int.from_bytes(b'\x00\x00\x01', 'big')  
# 1

For reference, see: http://docs.python.org/dev/library/stdtypes.html#int.from_bytes

like image 44
Jon Clements Avatar answered Oct 02 '22 08:10

Jon Clements


An alternative for python 2 and without the struct module would be:

>>> s = '\x61\x62\xff'
>>> a = sum([ord(b) * 2**(8*n) for (b, n) in zip(s, range(len(s))[::-1])])
>>> print a
6382335

where the byte ordering is big-endian. This gives the same result as with unutbu answer:

>>> print struct.unpack('>I', '\x00' + s)[0]
6382335

For little-endian byte ordering the conversion would be:

>>> a = sum([ord(b) * 2**(8*n) for (b, n) in zip(s, range(len(s)))])
>>> print a
16736865
>>> print struct.unpack('<I', s + '\x00')[0]
16736865
like image 27
cvr Avatar answered Oct 02 '22 07:10

cvr