Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculating 16-bit integer value from two 8-bit integers?

To illustrate what I mean: In a hex editor I have 8C 01 which is 396 little-endian. The data I'm working with is a tuple with two separate 8-bit integers i = (140, 1).

To calculate the 16-bit value my first approach was to simply multiply the 2nd integer by 255 then add the first. However this method is simply wrong as it does not give the correct value (due to my lack of knowledge). Can anyone provide a better (possibly Pythonic) approach?

like image 378
Helen Che Avatar asked Dec 07 '15 01:12

Helen Che


2 Answers

You need to multiply it with 256 (28). So the function would be something like:

def pack (tup) :
    return 256*tup[1]+tup[0]

or perform a bitwise shift, which makes more sense when working with bits:

def pack(tup) :
    return (tup[1]<<8)|tup[0]

here << means you place the value of tup[1] eight positions to the left. The pipe (|) means you perform an OR-operation. This is reasonable if you enforce the values in the tuple are less than 256 and can - at least theoretically - result in some speedup.

More generic

In case your tuple has an arbitrary length (for instance three, four, or more elements), you can define a more generic function:

def pack(tup) :
    sum = 0
    for i in range(len(tup)) :
        sum |= tup[i]<<(i<<3)
    return sum

Here <<3 is used as a shortcut to multiplying with 8, so an equivalent function would be:

def pack(tup) :
    sum = 0
    for i in range(len(tup)) :
        sum |= tup[i]<<(8*i)
    return sum

Or written out, it is something like:

tup[0]|(tup[1]<<8)|(tup[2]<<16)|(...)
like image 155
Willem Van Onsem Avatar answered Oct 15 '22 22:10

Willem Van Onsem


You should multiply by 256...

>>> i[1]*256 + i[0]
396

There is a Python way using struct module, but not necessary in such a simple case.

>>> from struct import pack, unpack
>>> unpack('<H', pack('BB', *i))[0]
396
like image 40
eph Avatar answered Oct 15 '22 23:10

eph