Python: XOR hex strings
Solution 1
You are missing a couple of things here.
First, you will not want to XOR those strings. You have the strings in an encoded form, therefore, you need to .decode()
them first:
binary_a = a.decode("hex")
binary_b = b.decode("hex")
Then, as already mentioned, the zip()
function stops iterating as soon as one of the two sequences is exhausted. No slicing is needed.
You need the second version of the loop: First, you want to get the ASCII value of the characters: ord()
produces a number. This is necessary because ^
only works on numbers.
After XORing the numbers, you then convert the number back into a character with chr
:
def xor_strings(xs, ys):
return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys))
xored = xor_strings(binary_a, binary_b).encode("hex")
Using .encode()
at the end, we get the binary string back into a form, that prints nicely.
Solution 2
int('', 16)
converts a hex string to an integer using base 16:
>>> int('f', 16)
15
>>> int('10', 16)
16
So do this:
result = int(a, 16) ^ int(b, 16) # convert to integers and xor them together
return '{:x}'.format(result) # convert back to hexadecimal
Related videos on Youtube
Kok Leong Fong
Updated on January 26, 2020Comments
-
Kok Leong Fong over 4 years
Possible Duplicate:
bitwise XOR of hex numbers in pythonI am trying to XOR two hex strings in Python and did not really know where to start from.
I have two hex strings:
a = "32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb" b = "32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f90"
Should I be using this ?
return "".join([chr((x) ^ (y)) for (x,y) in zip(a[:len(b)], b)])
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
I don't understand the difference with the two codes above. Why
chr
andord
? I have also seen people usingint(hex,16)
.-
phant0m over 11 yearsHave you read the documentation for
chr
andord
? -
Martijn Pieters over 11 yearsThe
a[:len(b)]
slice is redundant;zip()
will limit the result to the shortest of the inputs anyway. -
mgilson over 11 yearsAs a side note,
zip(a[:len(b)], b)
is the same thing aszip(a,b)
sincezip
stops iterating at the end of the shorter of the 2 iterables. -
mgilson over 11 years@MartijnPieters -- You win by 7 seconds ... :) (
try: Learn_Dvorak(); except RuntimeError: Lose_to_Martijn_again()
) -
Colonel Panic over 11 yearsRead this answer to that question stackoverflow.com/a/11119660/284795
-
Blckknght over 11 yearsThis is a good solution, as it works on all of the hex characters at once (giving a single integer) rather than character by character or byte by byte. Long hex strings will end up creating very large integers (which will use the
long
type in Python 2), but this is likely to be invisible to code that uses them. You can avoid needing to slice off the0x
bit by using string formatting, rather than thehex
builtin:"{:x}".format(16045690984833335023)
returns'deadbeefdeadbeef'
-
Blckknght over 11 yearsThis doesn't work on Python 3, where
str
objects don't have adecode
method (and where"hex"
is not a recognized encoding anyway). -
Facundo Casco over 11 yearsif the data in the strings is a number in hex, then using ord won't give you what you need,
ord("f") != 15
, just useint("f")
as glyphobet said -
phant0m over 11 years@F.C. That's why you do
decode()
first ;) -
phant0m over 11 years@Blckknght Python 3 wasn't specified in the tags, so it was safe to assume it wasn't needed. If you already know it won't work, why not point out the correct functions to use on Python 3?
-
Blckknght over 11 yearsI'm not sure if there is an easy way to do byte-by-byte decoding of a hex string to a byte string in Python 3. I didn't find one in my brief checking, and I think @glyphobet's solution to convert to integers rather than byte strings is better in general if you want to do math operations (like XOR) on the value.
-
glyphobet over 11 yearsGood point! I've updated the code to use
{:x}.format()
instead ofhex()
. Thanks. -
Raman Singh over 9 years@Blckknght nice ans. I just wanted to know how '{:x}.format()' works . Thx.