zfill significant manipulation least funcion example bitwise array python hex bit-manipulation xor

significant - python bit manipulation



XOR bit a bit de nĂºmeros hexadecimales en python (5)

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

Utilicé el código siguiente pero está devolviendo el valor de la 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)


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.


Si las cadenas tienen la misma longitud, entonces elegiría ''%x'' % () del xor incorporado ( ^ ).

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 usando una porción longer = longer[:len(shorter)]


Si las dos cadenas hexagonales tienen la misma longitud y quieres una salida de cadena hexagonal, puedes probar esto.

def hexxor(a, b): # xor two hex strings of the same length return "".join(["%x" % (int(x,16) ^ int(y,16)) for (x, y) in zip(a, b)])


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

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

Parece que ignoras 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 hace 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 existe un "número hexadecimal" en una variable de Python.
  • La función hex() se puede usar 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

Entonces puede hacer dos conversiones, realizar el XOR y luego convertir de nuevo a hexadecimal:

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


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)])])