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)
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:
0x
prefix. 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
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)])
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)]
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.