Bitwise XOR de números hexadecimales en Python

Salman Mehmood 21 junio 2023
Bitwise XOR de números hexadecimales en Python

El objetivo principal de este artículo es demostrar cómo trabajar con números XOR en un sistema numérico hexadecimal en Python.

Bitwise XOR de números hexadecimales en Python

XOR es un operador bit a bit, lo que significa OR exclusivo. Realiza la operación lógica en la que si ambas entradas (ya sea 0 o 1) son iguales, devuelve 1; de lo contrario, si los números de entrada son diferentes (como 0 y 1 o 1 y 0), la salida será 0.

XOR se usa normalmente en aplicaciones utilizadas para compresión, encriptación, gráficos o comunicación en cualquier forma. Al ser parte de los operadores lógicos Bitwise, XOR permite una mayor precisión y requiere menos recursos, lo que hace que el código sea mucho más rápido y eficiente.

Usando el operador ^, es bastante fácil XOR números en decimales. ¿Qué pasa con los números que inicialmente están en una cadena o son parte de ella?

Considere el siguiente código:

def strxor(a, b):
    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)])])


if __name__ == "__main__":

    print("1C2 ^ ABC = ", strxor("1C2", "ABC"))
    print("2FF ^ 78B = ", strxor("2FF", "78B"))
    print("29A ^ 90C = ", strxor("29A", "90C"))
    print("10C ^ 24B = ", strxor("10C", "24B"))
    print("BAD ^ 432 = ", strxor("BAD", "432"))
    print("54F ^ 123 = ", strxor("54F", "123"))

Esto da la salida a continuación:

1C2 ^ ABC =  1121113
2FF ^ 78B =  51264
29A ^ 90C =  1192
10C ^ 24B =  341
BAD ^ 432 =  118114118
54F ^ 123 =  46117

Verifiquemos nuestra solución:

if __name__ == "__main__":

    print("1C2 ^ 0xABC = ", 0x1C2 ^ 0xABC)
    print("2FF ^ 0x78B = ", 0x2FF ^ 0x78B)
    print("29A ^ 0x90C = ", 0x29A ^ 0x90C)
    print("10C ^ 0x24B = ", 0x10C ^ 0x24B)
    print("BAD ^ 0x432 = ", 0xBAD ^ 0x432)
    print("54F ^ 0x123 = ", 0x54F ^ 0x123)

Esto da la siguiente salida:

1C2 ^ 0xABC =  2942
2FF ^ 0x78B =  1396
29A ^ 0x90C =  2966
10C ^ 0x24B =  839
BAD ^ 0x432 =  3999
54F ^ 0x123 =  1132

Como se ve en el código anterior, hemos creado un nuevo método llamado strxor, que toma dos parámetros llamados a y b correspondientes a las dos cadenas pasadas a la función. El objetivo del método es tomar dos cadenas, aplicarles XOR y devolver el resultado (que también es una cadena).

Al verificar la solución, se ve que el resultado es diferente al esperado. En otras palabras, la función implementada strxor tiene un error lógico.

La solución a este problema puede abordarse de múltiples formas. Algunos de estos se definen de la siguiente manera:

Solución 1

def strxor(a, b):
    if len(a) > len(b):
        res = "".join(
            ["%x" % (int(x, 16) ^ int(y, 16)) for (x, y) in zip(a[: len(b)], b)]
        )
        return int("0x" + res, 0)
    else:
        res = "".join(
            ["%x" % (int(x, 16) ^ int(y, 16)) for (x, y) in zip(a, b[: len(a)])]
        )
        return int("0x" + res, 0)

Esto da la siguiente salida:

1C2 ^ ABC =  2942
2FF ^ 78B =  1396
29A ^ 90C =  2966
10C ^ 24B =  839
BAD ^ 432 =  3999
54F ^ 123 =  1132

En la solución mencionada anteriormente, se realizaron correcciones a la función original para mostrar el resultado correcto al inspeccionar lo que se cambió en el código en lugar de usar ord(), que devuelve el número que representa el código Unicode de un carácter específico.

Usamos int con los parámetros siendo una de las cadenas y un 16, refiriéndose a la base del número correspondiente a hexadecimal.

Solución 2

def strxor(a, b):
    if len(a) > len(b):
        res = "%x" % (int(a[: len(b)], 16) ^ int(b, 16))
        return int("0x" + res, 0)

    else:
        res = "%x" % (int(a, 16) ^ int(b[: len(a)], 16))
        return int("0x" + res, 0)

Esto da la siguiente salida:

1C2 ^ ABC =  2942
2FF ^ 78B =  1396
29A ^ 90C =  2966
10C ^ 24B =  839
BAD ^ 432 =  3999
54F ^ 123 =  1132

Este método no se basa en bucles for y zip. Es mucho más rápido que su contraparte en cuanto al tiempo de ejecución y el tiempo de ejecución general.

Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

Artículo relacionado - Python Hex