Converting a hexadecimal character to an int in Python

14,813

Solution 1

To get a NumPy array straight from a Python string, you can use

s = "\xff\x03"
a = numpy.frombuffer(s, numpy.uint8)

To get a list you can use

a =  map(ord, s)

An alternative to a list in Python 2.6 or above is to use bytesarray(s).

Solution 2

Try something like this:

a = '\xff'
print int(a.encode('hex'), 16)
255

Edit: sorry, the previous version had a mistake - decode instead of encode. This works.

Edit 2: I actually misread the question, as commenters noted. This may be already obvious but in case someone finds it helpful the regular python list solution would be:

>>> a = '\xff\xfe'
>>> [str(ord(char)) for char in a]
['255', '254']
>>> ' '.join([str(ord(char)) for char in a])
'255 254'

Solution 3

Here's a generalised approach that handles a hex string with variable length substrings, e.g.:

s = '5b1\n5\n3ad44'

The following code transforms a string with 3 million variable length hex substrings to a numpy integer array in 2 seconds (on a MacBook) through vectorisation:

import numpy as np, pandas as pd, cStringIO

s = ('5b1\n5\n3ad44\n' * 1000000)[:-1]    # 3m item hex string (variable element length)

# change hex to 2 digit decimal
for i in range(0,9): s = s.replace(str(i),'0' + str(i))  
for i in [['a','10'],['b','11'],['c','12'],['d','13'],['e','14'],['f','15']]:
    s = s.replace(i[0],i[1])

# read string into numpy
n = np.array(pd.read_csv(cStringIO.StringIO(s), header=None)[[0]]).astype('int64')    

# fix base
n = (n % 100) + 16 * ((n % 10000)/100) + 256 * ((n % 1000000)/10000) + 4096 * ((n % 100000000)/1000000) + 65536 * ((n % 10000000000)/100000000)

n[0:3]    # confirm correct transformation to [1457, 5, 240964]
Share:
14,813
John von N.
Author by

John von N.

Updated on July 22, 2022

Comments

  • John von N.
    John von N. almost 2 years

    I'm using the graphics library Pyglet to do some drawing and want to get the resulting image out as a Python list (so I can convert it to a NumPy array).

    Pyglet gives me a string of hex characters, like this: '\xff' (indicating a value of 255 at one pixel). How can I convert such a string to an int?

    I've tried int('\xff', 16), but that doesn't work. Note that according to the documentation, '\xnn' is escaped and encoded as a hexedecimal char, but it doesn't tell me how to convert that to an int.

  • Sven Marnach
    Sven Marnach about 13 years
    But this only works for a single byte, and for a single byte it is equivalent to ord(a), so it seems a bit pointless.
  • Sven Marnach
    Sven Marnach about 13 years
    Note that "\xff" is a string with a single character. Your answer suggests this string has four characters.
  • ThomasH
    ThomasH about 13 years
    @Sven It seems to work fine for longer strings int("\xff\x34\xbf\x25".encode('hex'),16) -> 4281646885L
  • Sven Marnach
    Sven Marnach about 13 years
    @ThomasH: This result is completely meaningless in the given context. To convert the string to a list of integers, each byte of the string has to be treated separately. Converting the whole string to a single integer certainly can be done this way, but this is completely unrelated to the question.
  • ThomasH
    ThomasH about 13 years
    @Sven You are right. I just found your "But this only works for a single byte" formulation misleading.
  • ThomasH
    ThomasH about 13 years
    @Sven You are right, but I just meant the last sentence metaphorically. Technically, the .encode approach from another answer would be the way to achieve that.