[python] bitwise XOR of hex numbers in python

how can we XOR hex numbers in python eg. I want to xor 'ABCD' to '12EF'. answer should be B922.

i used below code but it is returning garbage value

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)

This question is related to python hex bit-manipulation xor

The answer is


here's a better function

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

For performance purpose, here's a little code to benchmark these two alternatives:

#!/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')

Here are the results :

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

Seems like '%x' % (int(a,16)^int(b,16)) is faster then the zip version.


If the strings are the same length, then I would go for '%x' % () of the built-in xor (^).

Examples -

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

If the strings are not the same length, truncate the longer string to the length of the shorter using a slice longer = longer[:len(shorter)]


If the two hex strings are the same length and you want a hex string output then you might try this.

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. You're really over-complicating it by a very long distance. Try:

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

You seem to be ignoring these handy facts, at least:

  • Python has native support for hexadecimal integer literals, with the 0x prefix.
  • "Hexadecimal" is just a presentation detail; the arithmetic is done in binary, and then the result is printed as hex.
  • There is no connection between the format of the inputs (the hexadecimal literals) and the output, there is no such thing as a "hexadecimal number" in a Python variable.
  • The hex() function can be used to convert any number into a hexadecimal string for display.

If you already have the numbers as strings, you can use the int() function to convert to numbers, by providing the expected base (16 for hexadecimal numbers):

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

So you can do two conversions, perform the XOR, and then convert back to hex:

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

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to hex

Transparent ARGB hex value How to convert a hex string to hex number Javascript: Unicode string to hex Converting Hexadecimal String to Decimal Integer Convert string to hex-string in C# Print a variable in hexadecimal in Python Convert ascii char[] to hexadecimal char[] in C Hex transparency in colors printf() formatting for hex Python Hexadecimal

Examples related to bit-manipulation

What is (x & 1) and (x >>= 1)? 'and' (boolean) vs '&' (bitwise) - Why difference in behavior with lists vs numpy arrays? What does AND 0xFF do? bitwise XOR of hex numbers in python What is Bit Masking? What does a bitwise shift (left or right) do and what is it used for? Implement division with bit-wise operator How can I multiply and divide using only bit shifting and adding? In C/C++ what's the simplest way to reverse the order of bits in a byte? How do I get bit-by-bit data from an integer value in C?

Examples related to xor

bitwise XOR of hex numbers in python T-SQL XOR Operator XOR operation with two strings in java Creating a "logical exclusive or" operator in Java Is it good practice to use the xor operator for boolean checks?