Reputation: 531
For a cryptography application, I'm reading in strings that represent hexadecimal ( "36E06921", "27EA3C74" ) and need to xor them together and return a str of the result ("110A5555"). I'm able to xor char by char and get decimal result, but am having issues getting the ascii representation of the result. So, 0x3 xor 0x3 = 0x0. Whats the best way to get value 0 into ascii value 0x30?
Current attempt at implementation:
def xor_hexstrings(xs, ys):
bin_x = binascii.unhexlify(xs)
bin_y = binascii.unhexlify(ys)
hex_str = ""
for x,y in zip(xs, ys):
# fails, with error TypeError: 'int' does not support the buffer interface
xored = binascii.b2a_hex(int(x, 16) ^ int(y, 16))
hex_str += xored
return None
EDIT: Close, only issue is with zero. Following example shows recommended solution returns empty string for zero.
>>> hex(int('0', 16)).lstrip("0x")
''
>>> hex(int('1', 16)).lstrip("0x")
Upvotes: 0
Views: 798
Reputation: 155507
Adapting a pattern from Python 3 to the types available on Python 2: Use bytes-like objects to get natural int
iteration:
import binascii
from operator import xor
def xor_hex(xs, ys):
xs = bytearray(binascii.unhexlify(xs))
ys = bytearray(binascii.unhexlify(ys))
return binascii.hexlify(bytearray(map(xor, xs, ys))) # Stick a .upper() on this if it must produce uppercase hex
>>> print xor_hex( "36E06921", "27EA3C74" )
110a5555
In Python 3, it's simpler, since you can use bytes
types directly instead of converting from Py2 str
to bytearray
to get bytes
-like behavior:
def xor_hex(xs, ys):
xs = binascii.unhexlify(xs)
ys = binascii.unhexlify(ys)
return binascii.hexlify(bytes(map(xor, xs, ys)))
Although even that is fairly slow compared to what you can do with Python 3's int.to_bytes
and int.from_bytes
methods (which admittedly produce even uglier code).
Upvotes: 0
Reputation: 5902
You can do the following:
x = "36E06921"
y = "27EA3C74"
z = ''.join([format((int(i,16)^int(j,16)),'X') for i,j in zip(x,y)])
print z
Output:
110A5555
Upvotes: 2
Reputation: 380
I think what you are asking here is to convert an integer into it's respective string representation. At least that is what the example 0x0 -> 0x30 would seem to suggest. If so, just cast to a string in python with the str()
function.
>>> ord(str(0))
48
Just for reference 48 equals 0x30 and the ord() function gives you integer representation of a character.
EDIT: Check out the format function. Seems to have expected behavior!
>>> format(0x0, 'x')
'0'
Upvotes: -1
Reputation: 24768
I am guessing you need this:
>>> base10_int = int('0x0',16)
>>> base10_int_str = str(base10_int)
>>> base10_ascii_val = ord(base10_int_str)
>>> hex_ascii_val = hex(base10_ascii_val)
>>> hex_ascii_val
'0x30'
Upvotes: 0