Bitwise XOR of Hex Numbers in Python

Bitwise XOR of Hex Numbers in Python

The main aim of this article is to demonstrate how to work with XOR numbers in a hexadecimal number system in Python.

Bitwise XOR of Hex Numbers in Python

XOR is a bitwise operator, which means Exclusive OR. It performs the logical operation where if both inputs (either 0 or 1) are the same, then it returns 1; otherwise, if the input numbers are different (like 0 and 1 or 1 and 0), then the output will be 0.

XOR is normally used in applications used for compression, encryption, graphics, or communication in any form. Being a part of the Bitwise logical operators, XOR allows greater precision and requires fewer resources, thus making the code much faster and more efficient.

Using the ^ operator, it is fairly easy to XOR numbers in decimals. What about numbers that are initially in or part of a string?

Consider the following code:

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

This gives the output below:

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

Let us verify our solution:

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)

This gives the following output:

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

As seen from the code above, we have created a new method named strxor, which takes two parameters named a and b corresponding to the two strings passed to the function. The objective of the method is to take two strings, XOR them, and return the result (which also is a string).

Upon verification of the solution, it is seen that the result is different from what was expected. In other words, the implemented function strxor has a logical error.

The solution to this problem can be approached in multiple ways. Some of these are defined as follows:

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

This gives the following output:

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

In the solution mentioned above, fixes were made to the original function to show the correct output upon inspecting what was changed in the code instead of using ord(), which returns the number representing the Unicode code of a specified character.

We use int with the parameters being one of the strings and a 16, referring to the base of the number corresponding to hex.

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

This gives the following output:

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

This method does not rely on for loops and zip. It is much faster than its counterpart regarding runtime and overall execution time.

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

Related Article - Python Hex

  • Convert Binary to Hex in Python
  • Convert HEX to RGB in Python
  • Convert Hex to ASCII in Python
  • String to Hex in Python
  • Convert Hexadecimal to Decimal in Python