3

I have the next value

value = bytearray(b'\x85\x13\xbd|\xfb\xbc\xc3\x95\xbeL6L\xfa\xbf0U_`$]\xca\xee]z\xef\xa0\xd6(\x15\x8b\xca\x0e\x1f7\xa9\xf0\xa4\x98\xc5\xdf\xcdM5\xef\xc2\x052`\xeb\x13\xd9\x99B.\x95\xb2\xbd\x96\xd9\x14\xe6F\x9e\xfd\xd8\x00')

when I try to convert in python3.x it works well.

>>> int.from_bytes(value, byteorder='little')
2909369579440607969688280064437289348250138784421305732473112318543540722321676649649580720015118044118243611774710427666475769804427735898727217762490192773

How to convert it in python2.7? I already read the convert a string of bytes into an int (python)

struct.unpack(fmt, value)[0]

But don't know what to do with fmt.

Community
  • 1
  • 1
discort
  • 678
  • 1
  • 8
  • 26
  • You just want one great big number out form that? – LexyStardust Aug 14 '15 at 16:23
  • Yes I want. I can't imagine what I need to put to fmt. Is this length of the value? – discort Aug 14 '15 at 16:28
  • 2
    `struct.unpack` isn't appropriate for your case, you have too many bytes. You want http://stackoverflow.com/a/444814/8747 – Robᵩ Aug 14 '15 at 16:33
  • 1
    @Robᵩ: Almost, we need to reverse `value` to get the same number as in the OP. Eg, `int(str(value[::-1]).encode('hex'), 16)`. Or `sum(v << (8 * i) for i,v in enumerate(value))` – PM 2Ring Aug 14 '15 at 16:38

2 Answers2

6

You can just write your own from_bytes function in Python 2:

def from_bytes (data, big_endian = False):
    if isinstance(data, str):
        data = bytearray(data)
    if big_endian:
        data = reversed(data)
    num = 0
    for offset, byte in enumerate(data):
        num += byte << (offset * 8)
    return num

Used like this:

>>> data = b'\x85\x13\xbd|\xfb\xbc\xc3\x95\xbeL6L\xfa\xbf0U_`$]\xca\xee]z\xef\xa0\xd6(\x15\x8b\xca\x0e\x1f7\xa9\xf0\xa4\x98\xc5\xdf\xcdM5\xef\xc2\x052`\xeb\x13\xd9\x99B.\x95\xb2\xbd\x96\xd9\x14\xe6F\x9e\xfd\xd8\x00'
>>> from_bytes(data)
2909369579440607969688280064437289348250138784421305732473112318543540722321676649649580720015118044118243611774710427666475769804427735898727217762490192773L

As for struct, you cannot really use this, as it only supports unpacking elements of a certain kind, up to 8 byte integers. But since you want to handle arbitrary byte strings, you will have to use something else.

poke
  • 369,085
  • 72
  • 557
  • 602
4

You can use a combination of .encode('hex') and int(x, 16):

num = int(str(value).encode('hex'), 16)

Note that you need to use something like

int(''.join(reversed(value)).encode('hex'), 16)

in order to parse it as little endian.

reference: https://stackoverflow.com/a/444814/8747

Community
  • 1
  • 1
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • Note that you need to use something like `int(''.join(reversed(value)).encode('hex'), 16)` in order to parse it as *little* endian. – poke Aug 14 '15 at 16:37
  • 1
    After benchmarking, I found out that this is ridiculously faster than my solution although this is parsing a string… Good find! – poke Aug 14 '15 at 16:44
  • You can use `str(value[::-1])` instead of `''.join(reversed(value))` for little endian, not sure if there's any advantage to one over the other. – Mark Ransom Jul 15 '16 at 14:45