Domanda

I need to do an XOR of two hex strings so that each byte is XORed separately, but it doesn't work because the ord() function that I use seems to be getting an int as input instead of the intended string. Take a look at his code first to see what I mean:

from binascii import hexlify, unhexlify

def xor_hexstr(s1, s2):
    if len(s1) > len(s2):
        q = zip(unhexlify(s1[:len(s2)]), unhexlify(s2))
        return hexlify("".join(chr(ord(c1) ^ ord(c2)) for c1, c2 in q))

    else:
        q = zip(unhexlify(s2[:len(s1)]), unhexlify(s1))
        return hexlify("".join(chr(ord(c1) ^ ord(c2)) for c1, c2 in q))


t1 = "0ec17c9dabb8955c5dfb9cef627ddb4d"
t2 = "4ca00ff4c898d61e1edbf1800618fb28"

xor_hexstr(t1, t2)

And the error that I am getting:

TypeError: ord() expected string of length 1, but int found

I then checked the values of q, and they indeed where integers for some reason. I don't see why, because according to my logic they are supposed to be strings because I gave it a hex encoded string, unhexlified it and then stuck each character into a slot in q.

È stato utile?

Soluzione

You are using hexlify and unhexlify on Python 3, where they return a bytes object. You then zip these objects, which iterates over the bytes objects to create the pairs. Iteration over a bytes object produces integers. See the bytes type documentation:

While bytes literals and representations are based on ASCII text, bytes objects actually behave like immutable sequences of integers, with each value in the sequence restricted such that 0 <= x < 256.

You do not need to use ord() when looping over a bytes object; you already have integers representing the individual bytes.

Simply use a bytes object again after XOR-ing the values:

def xor_hexstr(s1, s2):
    if len(s1) > len(s2):
        q = zip(unhexlify(s1[:len(s2)]), unhexlify(s2))
    else:
        q = zip(unhexlify(s2[:len(s1)]), unhexlify(s1))

    return hexlify(bytes(c1 ^ c2 for c1, c2 in q))

Note that hexlify returns a bytes object too. If you have to have a string (unicode) object then decode from ASCII:

xor_hexstr(t1, t2).decode('ASCII')

Demo:

>>> xor_hexstr(t1, t2)
b'426173696320434243206d6f64652065'
>>> xor_hexstr(t1, t2).decode('ASCII')
'426173696320434243206d6f64652065'

Altri suggerimenti

from binascii import hexlify, unhexlify

def xor_hexstr(s1, s2):
    q = zip(unhexlify(s1), unhexlify(s2))
    return "".join(chr(c1 ^ c2) for c1, c2 in q)


s1 = "0ec17c9dabb8955c5dfb9cef627ddb4d"
s2 = "4ca00ff4c898d61e1edbf1800618fb28"

print(xor_hexstr(s1, s2))

output Basic CBC mode e

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top