2009-03-02 18 views
31

Tengo una cadena que puede ser un número hexadecimal con el prefijo "0x" o un número decimal sin un prefijo especial, excepto posiblemente un signo menos. "0x123" está en la base 16 y "-298" está en la base 10.cómo analizar hexadecimal o decimal int en Python

¿Cómo puedo convertir esto a un int o largo en Python?

No quiero usar eval() ya que es inseguro y exagerado.

+0

¿Por qué eval es inseguro? ¿Las personas malvadas van a introducir código en esos números? ¿Quién tiene acceso a esas cadenas? ¿No son dignos de confianza? –

+9

eval no es seguro porque permite la ejecución de código arbitrario. Si obtiene la cadena de una fuente confiable, sigue siendo insegura, sucede que confía en que esta fuente confiable no la aproveche. Si siempre has tenido el control de la cuerda, ¿por qué fue una cuerda? –

+0

Su programa python está disponible en formato fuente; también es un "código arbitrario". ¿Por qué trazar una línea entre un conjunto de fuentes de Python y otro? Eval no es menos seguro que ejecutar el programa Python en primer lugar. –

Respuesta

52
int("0x123", 0) 

(¿Por qué no int("0x123") hacer eso?)

+9

Es solo la forma en que se implementa int en Python: asume decimal a menos que explícitamente adivine al pasar 0 como la raíz. –

+2

Bueno, por lo que los ceros a la izquierda no lo hacen por defecto a oct. 'int (" 010 ")' devuelve '10'. –

+0

Pero Python no representa números octales con un cero inicial, deberían tener '0o' como el prefijo (por ejemplo,' 0o10'). Aún así, el caso de uso más común es convertir números decimales, y ese es el comportamiento predeterminado. –

5

Algo como esto podría ser lo que estás buscando.

def convert(aString): 
    if aString.startswith("0x") or aString.startswith("0X"): 
     return int(aString,16) 
    elif aString.startswith("0"): 
     return int(aString,8) 
    else: 
     return int(aString) 
+0

¿Por qué no utilizar 'if aString.upper(). Startswith ('0X'):' De esa manera no necesitarías el o? por supuesto 'lower()' with ''0x'' también funciona. – a2j

+0

@ a2j: No hay una buena razón. Sin embargo, lo que puedes hacer es usar 'timeit' para descubrir cuáles son las compensaciones. –

25

Base 16 a 10 (devolver un entero):

>>> int('0x123', 16) 
291 

base 10 al 16 (devolver una cadena):

>>> hex(291) 
'0x123' 
-2

Esta es una versión más simple que funciona como una encanto. Devuelve la cadena desde hexagonal() devuelve el mismo tipo:

def itoh(int): return hex(int)[2:] 
+1

El OP quiere convertir una cadena a un int. Tu código va por el otro camino. –

+0

Cunfusing para decir lo menos como usaste una palabra clave de python como un nombre del parámetro –

0

Si usted está haciendo un montón de ir entre los diferentes sistemas de numeración, la biblioteca bitstring crea una gran cantidad de operaciones binarias/Hex más fácil. También es compatible con la interpretación de cadenas:

http://pythonhosted.org/bitstring/