2013-07-11 70 views
0

我需要做一個XOR的兩個十六進制字符串,以便每個字節單獨XORed,但它不起作用,因爲我使用的ord()函數似乎越來越一個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的值,而且他們確實在那裏的一些整數原因。我不明白爲什麼,因爲根據我的邏輯,他們應該是字符串,因爲我給了它一個十六進制編碼的字符串,對它進行了未定義,然後將每個字符插入到q中的一個插槽中。

+1

爲什麼你傳遞's1', 's2'而不是't1','t2'? – falsetru

+0

對不起,這是一個錯字:D。儘管我的原始代碼沒有。 –

回答

1

您正在Python 3上使用hexlifyunhexlify,在那裏它們返回一個bytes對象。然後壓縮這些對象,這些對象遍歷bytes對象以創建對。對象上的迭代產生整數。看到bytes type documentation

雖然bytes文字和陳述都基於ASCII文本,bytes對象的行爲事實上象整數不可改變的序列,與限制,因此0 <= x < 256序列中的每個值。

當循環使用bytes對象時,不需要使用ord();你已經有有代表單個字節的整數。

簡單的異或值後再次使用bytes對象:

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對象了。如果您有一個字符串(Unicode)的對象,然後從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

相關問題