Jesh Kundem
Jesh Kundem

Reputation: 974

Numpy Int Array to HEX and then to String Conversion PYTHON

I have couple of questions

Say I have a numpy array

a = np.array([0,1,2,3,4,31])

a0 = a[0]
a1 = a[1]
a2 = a[2]
a3 = a[3]
a4 = a[4]
a5 = a[5]


print hex(a4), hex(a5)

gives me

   0x4L 0x1F

same for a0, a1, a2, a3,a5. I know the L is because of the numpy array.

Now how would I get 0x04 and not 0x4.

My required outcome is

'0x1F0403020100'

My required answer should start with 0x -- the hex values of a5, a4, a3, a2, a1, a0 - without the OX. The required output is a string. I can do the bit manipulation, if I have the zero. But not without it.

Upvotes: 0

Views: 6760

Answers (4)

Oliver Zendel
Oliver Zendel

Reputation: 2901

For python 3.5+:

'0x'+a.astype(np.uint8)[::-1].tobytes().hex().upper()

Upvotes: 0

Tasos Papastylianou
Tasos Papastylianou

Reputation: 22245

tl;dr

("0x" + ("{:0>2x}" * len(a))).format(*tuple(a[::-1]))


Explanation:

  • Multiply string "{:0>2x}" a number of times equal to len(a), i.e. do "{:0>2x}" * len(a). This will create the following string:

    '{:0>2x}{:0>2x}{:0>2x}{:0>2x}{:0>2x}{:0>2x}'
    

    {:0>2x} used inside a string can later be formated using the .format method, resulting in a translation of an int into a hexadecimal string, of width 2, where any padding is done with 0.
    Multiplying by the length of the array means you can create that many hex-formatted arguments.

  • Concatenate / prefix this string by "0x"
  • Reverse your array, since you want it reversed, by doing a[::-1]
  • Put the reversed array into a tuple, i.e. tuple(a[::-1]).
  • Expand this tuple using * syntax to make it into method arguments, i.e. *tuple(a[::-1])
  • Now you can use the expanded tuple as an argument to the .format method, on the concatenated string you created containing the custom formatting the correct number of times.

Result:

>>> ("0x" + ("{:0>2x}" * len(a))).format(*tuple(a[::-1]))
'0x1f0403020100'

PS. If you prefer capital hex strings, replace x with X, i.e.:

>>> ("0x" + ("{:0>2X}" * len(a))).format(*tuple(a[::-1]))
'0x1F0403020100'

Upvotes: 3

Moses Koledoye
Moses Koledoye

Reputation: 78554

You can try this workaround. An element wise hex conversion and a later join. '0x' is added to the start of the string:

>>> a = np.array([0,1,2,3,4,31])
>>> '0x' + ''.join('{:02X}'.format(i) for i in reversed(a))
'0x1F0403020100'

Upvotes: 2

What you really want to do is to store your array in a single number by shifting each element of the array by a certain (8) amount of bits:

>>> a = np.array([0,1,2,3,4,31])
>>> hex(sum([ai*256**i for i,ai in enumerate(a)]))
'0x1f0403020100'

But for this to work, you need to be sure that your array elements are at most 255. That's entirely up to you to keep/check. You should consider using an ndarray of dtype np.uint8, that way there's no chance for you to mangle up the data in your array (since you can't have overflow in your array).

Upvotes: 2

Related Questions