Matt
Matt

Reputation: 1573

Convert decimal int to little endian string ('\x##\x##...')

I want to convert an integer value to a string of hex values, in little endian. For example, 5707435436569584000 would become '\x4a\xe2\x34\x4f\x4a\xe2\x34\x4f'.

All my googlefu is finding for me is hex(..) which gives me '0x4f34e24a4f34e180' which is not what I want.

I could probably manually split up that string and build the one I want but I'm hoping somone can point me to a better option.

Upvotes: 4

Views: 27220

Answers (2)

Rutrus
Rutrus

Reputation: 1467

I know it is an old thread, but it is still useful. Here my two cents using python3:

hex_string = hex(5707435436569584202) # '0x4f34e24a4f34e180' as you said
bytearray.fromhex(hex_string[2:]).reverse()

So, the key is convert it to a bytearray and reverse it. In one line:

bytearray.fromhex(hex(5707435436569584202)[2:])[::-1] # bytearray(b'J\xe24OJ\xe24O')

PS: You can treat "bytearray" data like "bytes" and even mix them with b'raw bytes'

Update: As Will points in coments, you can also manage negative integers:

To make this work with negative integers you need to mask your input with your preferred int type output length. For example, -16 as a little endian uint32_t would be bytearray.fromhex(hex(-16 & (2**32-1))[2:])[::-1], which evaluates to bytearray(b'\xf0\xff\xff\xff')

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1124170

You need to use the struct module:

>>> import struct
>>> struct.pack('<Q', 5707435436569584000)
'\x80\xe14OJ\xe24O'
>>> struct.pack('<Q', 5707435436569584202)
'J\xe24OJ\xe24O'

Here < indicates little-endian, and Q that we want to pack a unsigned long long (8 bytes).

Note that Python will use ASCII characters for any byte that falls within the printable ASCII range to represent the resulting bytestring, hence the 14OJ, 24O and J parts of the above result:

>>> struct.pack('<Q', 5707435436569584202).encode('hex')
'4ae2344f4ae2344f'
>>> '\x4a\xe2\x34\x4f\x4a\xe2\x34\x4f'
'J\xe24OJ\xe24O'

Upvotes: 16

Related Questions