964

How do I convert a hex string to an integer?

"0xffff"   ⟶   65535
"ffff"     ⟶   65535
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Matt
  • 84,419
  • 25
  • 57
  • 67
  • 2
    If you just need to write an integer in hexadecimal format in your code, just write `0xffff` without quotes, [it's already an integer literal](https://docs.python.org/3/reference/lexical_analysis.html#integer-literals). – Boris Verkhovskiy Jan 23 '21 at 09:41

10 Answers10

1415

Without the 0x prefix, you need to specify the base explicitly, otherwise there's no way to tell:

x = int("deadbeef", 16)

With the 0x prefix, Python can distinguish hex and decimal automatically:

>>> print(int("0xdeadbeef", 0))
3735928559
>>> print(int("10", 0))
10

(You must specify 0 as the base in order to invoke this prefix-guessing behavior; if you omit the second parameter, int() will assume base-10.)

Olivia Stork
  • 4,660
  • 5
  • 27
  • 40
Dan Lenski
  • 76,929
  • 13
  • 76
  • 124
  • 66
    Which means you should always use 16 as the second argument. Explicit is better than implicit. – Bachsau Jan 13 '18 at 16:36
  • 29
    @bachsau, clearly untrue. What if you want to read user input, allowing input in hex or decimal, whichever is convenient for the user? – Dan Lenski Jan 13 '18 at 19:47
  • 26
    Ok, I should have said: In this particular case! The original question was "How do I convert a hex string…". If you want to leave it to the user, than it is a useful feature, with that you are right. – Bachsau Jan 13 '18 at 19:51
  • 1
    @DanLenski, it always converts hex strings to positive numbers. I want `int("FFFF",16)` to be converted to -1. – Nazar Mar 15 '20 at 22:38
  • 1
    @Nazar it has been a long time, so this is likely not useful for you at this point, but for anyone else who stumbles by here, if applying the two's complement rules is required. This answer may help https://stackoverflow.com/questions/1604464/twos-complement-in-python – Jeremy Apr 03 '20 at 14:08
  • @Nazar, you should stop and think for a moment about why that's a completely and utterly ambiguous request, and then write your own straightforward wrapper function that takes intended width in bits as an extra argument. – Dan Lenski Aug 17 '20 at 09:27
  • I've just used this in some code where I have a list of MAC-Addresses. Given a valid MAC-Address in the variable `mac` you can use `int(mac.replace(':',''), 16)`. – dom Dec 19 '22 at 11:16
221

int(hexstring, 16) does the trick, and works with and without the 0x prefix:

>>> int("a", 16)
10
>>> int("0xa", 16)
10
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
unwind
  • 391,730
  • 64
  • 469
  • 606
  • where is the 16 for? – Max Oct 27 '20 at 11:47
  • 2
    @Max the `16` is for [base 16](https://en.wikipedia.org/wiki/Base_16). Normally people use base 10 (and in Python there's an implicit `10` when you don't pass a second argument to `int()`), where you start at `0` then count up `0123456789` (10 digits in total) before going back to `0` and adding 1 to the next units place. In base 16 (also called "hexadecimal" or "hex" for short) you start at `0` then count up `0123456789ABCDEF` (16 digits in total). The `int` function accepts any number from 2 and 36 as the base, it just extends the alphabet: base 36 is `0123456789ABCEDFGHIJKLMNOPQRSTUVWXYZ`. – Boris Verkhovskiy Jan 23 '21 at 09:16
55

Convert hex string to int in Python

I may have it as "0xffff" or just "ffff".

To convert a string to an int, pass the string to int along with the base you are converting from.

Both strings will suffice for conversion in this way:

>>> string_1 = "0xffff"
>>> string_2 = "ffff"
>>> int(string_1, 16)
65535
>>> int(string_2, 16)
65535

Letting int infer

If you pass 0 as the base, int will infer the base from the prefix in the string.

>>> int(string_1, 0)
65535

Without the hexadecimal prefix, 0x, int does not have enough information with which to guess:

>>> int(string_2, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 0: 'ffff'

literals:

If you're typing into source code or an interpreter, Python will make the conversion for you:

>>> integer = 0xffff
>>> integer
65535

This won't work with ffff because Python will think you're trying to write a legitimate Python name instead:

>>> integer = ffff
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'ffff' is not defined

Python numbers start with a numeric character, while Python names cannot start with a numeric character.

Community
  • 1
  • 1
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
  • Worth repeating "Letting int infer If you pass 0 as the base, int will infer the base from the prefix in the string." How to convert from hexadecimal or decimal (or binary) to integer as python interpreter does. – gaoithe Oct 10 '19 at 11:20
51

For any given string s:

int(s, 16)
Jorge Ferreira
  • 96,051
  • 25
  • 122
  • 132
16

Adding to Dan's answer above: if you supply the int() function with a hex string, you will have to specify the base as 16 or it will not think you gave it a valid value. Specifying base 16 is unnecessary for hex numbers not contained in strings.

print int(0xdeadbeef) # valid

myHex = "0xdeadbeef"
print int(myHex) # invalid, raises ValueError
print int(myHex , 16) # valid
Max
  • 261
  • 1
  • 4
  • 9
14

Please don't do this!

>>> def hex_to_int(x):
    return eval("0x" + x)

>>> hex_to_int("c0ffee")
12648430

Why is using 'eval' a bad practice?

15000+ examples of this in the wild.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
André Laszlo
  • 15,169
  • 3
  • 63
  • 81
  • 3
    It's worth noting that `eval` is also absurdly slow, on top of all of the other issues with it. – j6m8 Nov 01 '15 at 20:22
  • 6
    If this is a bad idea, then what is the point of bringing it up? – pppery Jul 31 '17 at 19:29
  • 4
    Good point. Partly because I think it's funny and partly because I've seen it in production code. – André Laszlo Jul 31 '17 at 19:57
  • I should probably note I used to do this after experiencing issues with `int(s,16)` returning improper values, causing some major issues with my runtime (`int(hex(value),16) == int(value) >>> False`). the string supplied to `eval()` was safe and the value returned was proper. – Tcll Jun 14 '19 at 18:51
  • @Tcll Wow that's strange, which Python version were you using? Did you make a note of the values that caused the issue? – André Laszlo Jun 14 '19 at 19:23
  • @AndréLaszlo I'm not entirely sure, but if it was from that long ago, I can probably guess it's portable python 2.7.5, and no I don't remember the values I'm afraid... I was a noob at the time, so I didn't keep track of as much as I do now, but I use Anaconda 2.3.0 as my portable interpreter these days, and I just tried a few very large data sets where everything matched appropriately... not sure how well I trust it overall though. – Tcll Jun 14 '19 at 23:25
  • 1
    i found this to be funny and enlightening, im glad it was posted – Sidharth Ghoshal May 06 '20 at 01:19
  • This doesn't answer the question, because it fails on `"0xffff"`. – marcelm Oct 14 '20 at 15:47
  • 2
    Just got a downvote, but I'll leave this answer since it's still... very common: https://github.com/search?l=Python&q=%27eval%28%220x%22%27&type=Code – André Laszlo Mar 16 '21 at 18:26
  • Current state: https://github.com/search?q=%28%22eval%28%5C%220x%5C%22%22+OR+%22eval%28f%5C%220x%22+OR+%22eval%28%270x%22%29+language%3Apython&type=code – André Laszlo Jul 17 '23 at 10:06
7

Or ast.literal_eval (this is safe, unlike eval):

ast.literal_eval("0xffff")

Demo:

>>> import ast
>>> ast.literal_eval("0xffff")
65535
>>> 
U13-Forward
  • 69,221
  • 14
  • 89
  • 114
4

If you are using the python interpreter, you can just type 0x(your hex value) and the interpreter will convert it automatically for you.

>>> 0xffff

65535
maysara
  • 5,873
  • 2
  • 23
  • 34
1

The formatter option '%x' % seems to work in assignment statements as well for me. (Assuming Python 3.0 and later)

Example

a = int('0x100', 16)
print(a)   #256
print('%x' % a) #100
b = a
print(b) #256
c = '%x' % a
print(c) #100
Soundararajan
  • 2,000
  • 21
  • 23
  • The comments are incorrect. `print(b)` will output `256`, not `100` and `print(c)` will output `100`, not `256`. Also note that `c` is a string, but `a` is not so your answer actually converts an int to a string, not the other way around (this is what the question is about). – André Laszlo Aug 07 '15 at 16:04
  • Thanks for your input, i agree that my answer is not right, and now i have fixed it. However i realize that part of the answer is redundant as above i.e using int(string, base), but still the rest of the answer adds more options to the post, i believe. Agree ? – Soundararajan Aug 10 '15 at 09:44
  • Not relevant; this is about converting from base 16 to base 10, not the other way around – pppery Aug 01 '17 at 20:46
1

Handles hex, octal, binary, int, and float

Using the standard prefixes (i.e. 0x, 0b, 0, and 0o) this function will convert any suitable string to a number. I answered this here: https://stackoverflow.com/a/58997070/2464381 but here is the needed function.

def to_number(n):
    ''' Convert any number representation to a number 
    This covers: float, decimal, hex, and octal numbers.
    '''

    try:
        return int(str(n), 0)
    except:
        try:
            # python 3 doesn't accept "010" as a valid octal.  You must use the
            # '0o' prefix
            return int('0o' + n, 0)
        except:
            return float(n)
shrewmouse
  • 5,338
  • 3
  • 38
  • 43
  • 1
    @SergeyVoronezhskiy, 3.8.2 and 3.9 still don't recognize '010' as an octal (decimal 8). It seems that they still require the ``0o`` prefix. I'm sure that this is to avoid interpreting 0 padded numbers as the very uncommon octal. So, really nothing has changed since I posted this answer in 2019. – shrewmouse Nov 12 '20 at 18:52