2013-07-11 2 views
0

Мне нужно сделать XOR из двух шестнадцатеричных строк, чтобы каждый байт был XORed отдельно, но он не работает, потому что функция ord(), которую я использую, кажется, получает a int в качестве ввода вместо предполагаемой строки. Посмотрите на свой код первым, чтобы увидеть, что я имею в виду:Unhexlify, кажется, дает мне int, когда я хочу строку

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) 

и ошибка, что я получаю:

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

Затем я проверил значения ц, и они действительно где целые числа для некоторых причина. Я не понимаю, почему, потому что, согласно моей логике, они должны быть строками, потому что я дал ему строку с шестнадцатеричным кодированием, неэксклюстил ее, а затем закрепил каждый символ в слот в q.

+1

Почему вы проходите 's1', 's2' вместо' t1', 't2'? – falsetru

+0

Извините, falsetru, была опечатка: D. Однако у меня нет этого в моем исходном коде. –

ответ

1

Вы используете hexlify и unhexlify на Python 3, где они возвращают объект bytes. Затем вы zip эти объекты, которые итерации над объектами bytes для создания пар. Итерация над объектом bytes создает целые числа. ВИДЕТЬ bytes type documentation:

В то время как bytes литералов и представления основаны на ASCII текст, bytes объекты на самом деле ведут себя как неизменяемые последовательности целых чисел, каждое значение в последовательности запретной такое, что 0 <= x < 256.

Нельзя использовать ord() при обходе объекта bytes; вы уже имеют целые числа, представляющие отдельные байты.

Просто используйте bytes объект снова после XOR-ки значения:

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

Обратите внимание, что hexlify Возвращает bytes объект тоже. Если есть иметь строку (юникод) объект затем декодировать из ASCII:

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

Демо:

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

Спасибо! Ваше решение сработало, и ваше объяснение было хорошим: D. –

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

выход Basic CBC mode e