Convertir cadena hexadecimal a int en Python

766

¿Cómo convierto una cadena hexadecimal a un int en Python?

Puedo tenerlo como " 0xffff" o simplemente " ffff".

Mate
fuente

Respuestas:

1087

Sin el prefijo 0x, debe especificar la base explícitamente, de lo contrario no hay forma de saber:

x = int("deadbeef", 16)

Con el prefijo 0x, Python puede distinguir hexadecimal y decimal automáticamente.

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

( Debe especificar 0como base para invocar este comportamiento de adivinación de prefijo; omitir el segundo parámetro significa asumir base-10).

Dan Lenski
fuente
25
Lo que significa que siempre debe usar 16 como segundo argumento. Explícito es mejor que implícito.
Bachsau
13
@bachsau, claramente falso. ¿Qué sucede si desea leer la entrada del usuario, permitiendo la entrada en hexadecimal o decimal, lo que sea conveniente para el usuario?
Dan Lenski el
77
Ok, debería haber dicho: ¡En este caso particular! La pregunta original era "¿Cómo convierto una cadena hexadecimal ...". Si desea dejarlo al usuario, entonces es una característica útil, con eso tiene razón.
Bachsau
@DanLenski, siempre convierte cadenas hexadecimales a números positivos. Quiero int("FFFF",16)convertirme a -1.
Nazar
@Nazar ha pasado mucho tiempo, por lo que es probable que esto no sea útil para usted en este momento, pero para cualquier otra persona que tropiece por aquí, si es necesario aplicar las reglas del complemento de los dos. Esta respuesta puede ayudar a stackoverflow.com/questions/1604464/twos-complement-in-python
Jeremy
163

int(hexString, 16) hace el truco y funciona con y sin el prefijo 0x:

>>> int("a", 16)
10
>>> int("0xa",16)
10
relajarse
fuente
47

Para cualquier cadena dada s:

int(s, 16)
Jorge Ferreira
fuente
43

Convertir cadena hexadecimal a int en Python

Puedo tenerlo como "0xffff"o solo "ffff".

Para convertir una cadena en un int, pasa la cadena intjunto con la base desde la que estás convirtiendo.

Ambas cadenas serán suficientes para la conversión de esta manera:

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

Dejar intinferir

Si pasa 0 como base, intinferirá la base del prefijo en la cadena.

>>> int(string_1, 0)
65535

Sin el prefijo hexadecimal, 0x, intno tiene suficiente información con la que adivinar:

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

literales:

Si está escribiendo en el código fuente o en un intérprete, Python hará la conversión por usted:

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

Esto no funcionará ffffporque Python pensará que estás intentando escribir un nombre legítimo de Python en su lugar:

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

Los números de Python comienzan con un carácter numérico, mientras que los nombres de Python no pueden comenzar con un carácter numérico.

Aaron Hall
fuente
Vale la pena repetir "Dejar int inferir Si pasa 0 como base, int inferirá la base del prefijo en la cadena". Cómo convertir de hexadecimal o decimal (o binario) a entero como lo hace el intérprete de Python.
gaoithe
13

Agregando a la respuesta de Dan anterior: si proporciona la función int () con una cadena hexadecimal, tendrá que especificar la base como 16 o no pensará que le dio un valor válido. No es necesario especificar la base 16 para los números hexadecimales no contenidos en las cadenas.

print int(0xdeadbeef) # valid

myHex = "0xdeadbeef"
print int(myHex) # invalid, raises ValueError
print int(myHex , 16) # valid
Max
fuente
5

La peor manera:

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

>>> hex_to_int("c0ffee")
12648430

¡Por favor no hagas esto!

¿Usar eval en Python es una mala práctica?

André Laszlo
fuente
3
Vale la pena señalar que evaltambién es absurdamente lento, además de todos los otros problemas con él.
j6m8
44
Si esta es una mala idea, ¿cuál es el punto de plantearla?
pppery
3
Buen punto. En parte porque creo que es divertido y en parte porque lo he visto en el código de producción.
André Laszlo
Probablemente debería tener en cuenta que solía hacer esto después de experimentar problemas con la int(s,16)devolución de valores incorrectos, causando algunos problemas importantes con mi tiempo de ejecución ( int(hex(value),16) == int(value) >>> False). la cadena suministrada a eval()era segura y el valor devuelto era correcto.
Tcll
1
Me pareció divertido e ilustrativo, me alegro de que se haya publicado
frogeyedpeas
3

O ast.literal_eval(esto es seguro, a diferencia eval):

ast.literal_eval("0xffff")

Manifestación:

>>> import ast
>>> ast.literal_eval("0xffff")
65535
>>> 
U10-Adelante
fuente
1

La opción de formateador '% x'% parece funcionar también en las declaraciones de asignación para mí. (Suponiendo Python 3.0 y posterior)

Ejemplo

a = int('0x100', 16)
print(a)   #256
print('%x' % a) #100
b = a
print(b) #256
c = '%x' % a
print(c) #100
Soundararajan
fuente
Los comentarios son incorrectos. print(b)dará salida 256, no 100y print(c)dará salida 100, no 256. También tenga en cuenta que ces una cadena, pero ano es así, su respuesta en realidad convierte un int en una cadena, y no al revés (de esto se trata la pregunta).
André Laszlo
Gracias por su aporte, estoy de acuerdo en que mi respuesta no es correcta, y ahora la he solucionado. Sin embargo, me doy cuenta de que parte de la respuesta es redundante como anteriormente, es decir, usando int (string, base), pero aún así el resto de la respuesta agrega más opciones a la publicación, creo. De acuerdo ?
Soundararajan
Irrelevante; se trata de convertir de la base 16 a la base 10, no al revés
pppery
1

Si está utilizando el intérprete de Python, puede escribir 0x (su valor hexadecimal) y el intérprete lo convertirá automáticamente.

>>> 0xffff

65535
Maysara Alhindi
fuente
1

Maneja hexadecimal, octal, binario, int y flotante

Usando los prefijos estándar (es decir, 0x, 0b, 0 y 0o) esta función convertirá cualquier cadena adecuada a un número. Respondí esto aquí: https://stackoverflow.com/a/58997070/2464381 pero aquí está la función necesaria.

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)
musaraña
fuente
-1

En Python 2.7, int('deadbeef',10)no parece funcionar.

Lo siguiente funciona para mí:

>>a = int('deadbeef',16)
>>float(a)
3735928559.0
Avi2503
fuente
44
¿Cómo responde esto a la pregunta?
pppery
-5

con el prefijo '0x', también puede usar la función eval

Por ejemplo

>>a='0xff'
>>eval(a)
255
Junjie
fuente
16
Asegúrese de que la validación de entrada se realice correctamente si usa eval. De hecho, probablemente hay una mejor manera. No uses eval.
ALOToverflow
77
Por lo menos deberías estar usando ast.literal_eval.
Andy Hayden
2
También muy lento. La peor de todas.
Tõnu Samuel