I have to convert a number to a list depending on its decimal value. For example, the number 300
(0x012C
) would be [1, 44]
because 1
and 44
are 0x01
and 0x2c
respectively.
How can I do that?
I have to convert a number to a list depending on its decimal value. For example, the number 300
(0x012C
) would be [1, 44]
because 1
and 44
are 0x01
and 0x2c
respectively.
How can I do that?
Here's a basic approach:
In [10]: def by_two_byte(number, mod=16*16):
...: rest, rem = number // mod, number % mod
...: if not rest:
...: return [rem]
...: else:
...: return by_two_byte(rest, mod) + [rem]
...:
...:
In [11]: by_two_byte(300)
Out[11]: [1, 44]
In [12]: by_two_byte(9635)
Out[12]: [37, 163]
You could also do this iteratively, but likely it won't be necessary unless you are dealing with very large integers. Note, the above function takes int
input, so pass it int('300')
if you want to start with a string.
Note the way this generalizes:
In [13]: 0xaf23ff65
Out[13]: 2938371941
In [14]: by_two_byte(2938371941)
Out[14]: [175, 35, 255, 101]
In [15]: list(map(hex,by_two_byte(2938371941)))
Out[15]: ['0xaf', '0x23', '0xff', '0x65']
In [16]: 0x4f8ac # odd number of hexadecimal digits
Out[16]: 325804
In [17]: list(map(hex,by_two_byte(325804)))
Out[17]: ['0x4', '0xf8', '0xac']
Dispensing with the decimal literals, using hexadeciml literals:
In [18]: list(map(hex, by_two_byte(0xfffffffff)))
Out[18]: ['0xf', '0xff', '0xff', '0xff', '0xff']
In [19]: list(map(hex, by_two_byte(0xfafbfcfd)))
Out[19]: ['0xfa', '0xfb', '0xfc', '0xfd']
For an iterative approach:
def convertToByteList(num):
byteList = []
while num > 0:
byteList.insert(0, num & 0xFF)
num = num >> 8
return byteList
Or in one line:
[num >> (8*i) & 0xFF for i in range((num.bit_length() - 1) // 8,-1,-1)]
This uses shifting and bit masking to extract each byte, and uses the length of the integer in bits to determine how long the list should be.
If you're using Python 3, then the int.to_bytes
method does most of what you need:
>>> n = 300
>>> n.to_bytes(2, "big")
b'\x01,'
>>> list(n.to_bytes(2, "big"))
[1, 44]
That 2
is the number of bytes in the output; it's a required argument. You can compute how many bytes you need for a given n
using the int.bit_length
method:
>>> n = 9635
>>> nbytes = -(-n.bit_length() // 8) # divide by 8, round up
>>> list(n.to_bytes(nbytes, "big"))
[37, 163]
And a larger example:
>>> n = 2160376691
>>> list(n.to_bytes(-(-n.bit_length()//8), "big"))
[128, 196, 187, 115]
So, you're trying to convert you decimal integer to a hex digits pair. For small (16-bit decimal ints), you can do it like this:
>>> list(divmod(300,256))
[1, 44]
>>> list(divmod(9635,256))
[37, 163]