XOR a nivel de bits de números hexadecimales en python

¿Cómo podemos XOR números hexadecimales en python, por ejemplo. Quiero xor ‘ABCD’ a ’12EF’. la respuesta debe ser B922.

Usé el siguiente código pero está devolviendo valor de basura

def strxor(a, b): # xor two strings of different lengths if len(a) > len(b): return "".join(["%s" % (ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)]) else: return "".join(["%s" % (ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])]) key ='12ef' m1='abcd' print strxor(key,m1) 

Related of "XOR a nivel de bits de números hexadecimales en python"

Whoa Realmente lo estás complicando demasiado por una distancia muy larga. Tratar:

 >>> print hex(0x12ef ^ 0xabcd) 0xb922 

Parece que estás ignorando estos hechos útiles, al menos:

  • Python tiene soporte nativo para literales enteros hexadecimales, con el prefijo 0x .
  • “Hexadecimal” es solo un detalle de presentación; la aritmética se realiza en binario, y luego el resultado se imprime como hexadecimal.
  • No hay conexión entre el formato de las entradas (los literales hexadecimales) y la salida, no hay tal cosa como un “número hexadecimal” en una variable de Python.
  • La función hex() se puede utilizar para convertir cualquier número en una cadena hexadecimal para su visualización.

Si ya tiene los números como cadenas, puede usar la función int() para convertir a números, proporcionando la base esperada (16 para números hexadecimales):

 >>> print int("12ef", 16) 4874 

Así que puedes hacer dos conversiones, realizar el XOR y luego volver a convertir al hex:

 >>> print hex(int("12ef", 16) ^ int("abcd", 16)) 0xb922 

Si las dos cadenas hexagonales tienen la misma longitud y desea una salida de cadena hexadecimal, puede intentar esto.

 def hexxor (a, b): # xo dos cadenas hexadecimales de la misma longitud
     return "" .join (["% x"% (int (x, 16) ^ int (y, 16)) para (x, y) en zip (a, b)])

Si las cadenas tienen la misma longitud, iría por '%x' % () del xor integrado ( ^ ).

Ejemplos –

 >>>a = '290b6e3a' >>>b = 'd6f491c5' >>>'%x' % (int(a,16)^int(b,16)) 'ffffffff' >>>c = 'abcd' >>>d = '12ef' >>>'%x' % (int(a,16)^int(b,16)) 'b922' 

Si las cadenas no tienen la misma longitud, trunca la cadena más larga a la longitud de la más corta utilizando una división longer = longer[:len(shorter)]

Aquí hay una mejor función

 def strxor(a, b): # xor two strings of different lengths if len(a) > len(b): return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)]) else: return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])]) 

Para fines de rendimiento, aquí hay un pequeño código para comparar estas dos alternativas:

 #!/bin/python def hexxorA(a, b): if len(a) > len(b): return "".join(["%x" % (int(x,16) ^ int(y,16)) for (x, y) in zip(a[:len(b)], b)]) else: return "".join(["%x" % (int(x,16) ^ int(y,16)) for (x, y) in zip(a, b[:len(a)])]) def hexxorB(a, b): if len(a) > len(b): return '%x' % (int(a[:len(b)],16)^int(b,16)) else: return '%x' % (int(a,16)^int(b[:len(a)],16)) def testA(): strstr = hexxorA("b4affa21cbb744fa9d6e055a09b562b87205fe73cd502ee5b8677fcd17ad19fce0e0bba05b1315e03575fe2a783556063f07dcd0b9d15188cee8dd99660ee751", "5450ce618aae4547cadc4e42e7ed99438b2628ff15d47b20c5e968f086087d49ec04d6a1b175701a5e3f80c8831e6c627077f290c723f585af02e4c16122b7e2") if not int(strstr, 16) == int("e0ff3440411901bd57b24b18ee58fbfbf923d68cd88455c57d8e173d91a564b50ce46d01ea6665fa6b4a7ee2fb2b3a644f702e407ef2a40d61ea3958072c50b3", 16): raise KeyError return strstr def testB(): strstr = hexxorB("b4affa21cbb744fa9d6e055a09b562b87205fe73cd502ee5b8677fcd17ad19fce0e0bba05b1315e03575fe2a783556063f07dcd0b9d15188cee8dd99660ee751", "5450ce618aae4547cadc4e42e7ed99438b2628ff15d47b20c5e968f086087d49ec04d6a1b175701a5e3f80c8831e6c627077f290c723f585af02e4c16122b7e2") if not int(strstr, 16) == int("e0ff3440411901bd57b24b18ee58fbfbf923d68cd88455c57d8e173d91a564b50ce46d01ea6665fa6b4a7ee2fb2b3a644f702e407ef2a40d61ea3958072c50b3", 16): raise KeyError return strstr if __name__ == '__main__': import timeit print("Time-it 100k iterations :") print("\thexxorA: ", end='') print(timeit.timeit("testA()", setup="from __main__ import testA", number=100000), end='s\n') print("\thexxorB: ", end='') print(timeit.timeit("testB()", setup="from __main__ import testB", number=100000), end='s\n') 

Aquí están los resultados :

 Time-it 100k iterations : hexxorA: 8.139988073991844s hexxorB: 0.240523161992314s 

Parece que '%x' % (int(a,16)^int(b,16)) es más rápido que la versión zip.