Bienvenido a proyecto on line, en este sitio vas a hallar la respuesta que buscabas.
Solución:
(1) Usar int() funciona muy bien para esto, y Python hace todas las comprobaciones por ti 🙂
int('00480065006C006C006F00200077006F0072006C00640021', 16)
6896377547970387516320582441726837832153446723333914657L
trabajará. En caso de falla, recibirá un ValueError
excepción.
Breve ejemplo:
int('af', 16)
175
int('ah', 16)
...
ValueError: invalid literal for int() with base 16: 'ah'
(2) Un alternativa sería recorrer los datos y asegurarse de que todos los caracteres estén dentro del rango de 0..9
y a-f/A-F
. string.hexdigits
('0123456789abcdefABCDEF'
) es útil para esto ya que contiene ambas cosas dígitos en mayúsculas y minúsculas.
import string
all(c in string.hexdigits for c in s)
regresará tampoco True
o False
en base a la vigencia de sus datos en string s
.
Breve ejemplo:
s = 'af'
all(c in string.hexdigits for c in s)
True
s = 'ah'
all(c in string.hexdigits for c in s)
False
notas:
Como @ScottGriffiths señala correctamente en un comentario a continuación, el int()
enfoque funcionará si su string contiene 0x
al principio, mientras que la verificación de carácter por carácter fallará con esto. Además, comprobando contra un colocar de caracteres es más rápido que un string de caracteres, pero es dudoso que esto importe con cadenas de SMS cortas, a menos que procese muchos (¡muchos!) de ellos en secuencia, en cuyo caso podría convertir stringhexditigs en un conjunto con set(string.hexdigits)
.
Puede:
- probar si el string contiene solo dígitos hexadecimales (0…9,A…F)
- tratar de convertir el string a entero y ver si falla.
Aquí está el código:
import string
def is_hex(s):
hex_digits = set(string.hexdigits)
# if s is long, then it is faster to check against a set
return all(c in hex_digits for c in s)
def is_hex(s):
try:
int(s, 16)
return True
except ValueError:
return False
Sé que el operador mencionó expresiones regulares, pero quería contribuir con una solución de este tipo por el bien de la integridad:
def is_hex(s):
return re.fullmatch(r"^[0-9a-fA-F]$", s or "") is not None
Actuación
Para evaluar el rendimiento de las diferentes soluciones propuestas aquí, utilicé el módulo timeit de Python. Las cadenas de entrada se generan aleatoriamente para tres longitudes diferentes, 10
, 100
, 1000
:
s=''.join(random.choice('0123456789abcdef') for _ in range(10))
Soluciones de Levon:
# int(s, 16)
10: 0.257451018987922
100: 0.40081690801889636
1000: 1.8926858339982573
# all(_ in string.hexdigits for _ in s)
10: 1.2884491360164247
100: 10.047717947978526
1000: 94.35805322701344
Otras respuestas son variaciones de estas dos. Usando una expresión regular:
# re.fullmatch(r'^[0-9a-fA-F]$', s or '')
10: 0.725040541990893
100: 0.7184272820013575
1000: 0.7190397029917222
Por lo tanto, elegir la solución correcta depende de la longitud de la entrada string y si las excepciones se pueden manejar de manera segura. La expresión regular ciertamente maneja cadenas grandes mucho más rápido (y no arrojará un ValueError
en desbordamiento), pero int()
es el ganador para cadenas más cortas.
Sección de Reseñas y Valoraciones
Si eres capaz, puedes dejar un ensayo acerca de qué te ha parecido este ensayo.