[英]Xor encryption/decryption of a file with Python 3
我需要使用xor使用Python 3加密/解密文件,我有一個在Python 2中運行良好的代碼,但是當我嘗試將其調整到Python 3時,給我一些我無法解決的錯誤。
這段代碼在Python 2.7中運行良好:
from itertools import cycle
def xore(data, key):
return ''.join(chr(ord(a) ^ ord(b)) for (a, b) in zip(data, cycle(key)))
with open('inputfile.jpg', 'rb') as encry, open('outputfile.jpg', 'wb') as decry:
decry.write(xore(encry.read(), 'anykey'))
嘗試在python 3中保持不變時的錯誤:
Traceback (most recent call last):
File "ask.py", line 8, in <module>
decry.write(xore(encry.read(), 'anykey'))
File "ask.py", line 5, in xore
return ''.join(chr(ord(a) ^ ord(b)) for (a, b) in zip(data, cycle(key)))
File "ask.py", line 5, in <genexpr>
return ''.join(chr(ord(a) ^ ord(b)) for (a, b) in zip(data, cycle(key)))
TypeError: ord() expected string of length 1, but int found
如果有人可以解釋並幫助我將此代碼改編為Python 3。
a
已經是一個int
所以你需要刪除對ord(a)
的調用:
def xore(data, key):
return ''.join(chr(a ^ ord(b)) for (a, b) in zip(data, cycle(key)))
如果沒有.encode("utf-8")
,你將無法將連接的字符串寫入你的outfile,這將不會給你任何可用的輸出,所以不確定你實際上想要實現什么。
您可以看到索引字節字符串時在python3中得到一個int:
n [1]: s = b"foo"
In [2]: s[0]
Out[2]: 102 # f
在python2中你得到str / char:
In [1]: s = b"foo"
In [2]: s[0]
Out[2]: 'f'
迭代或調用next也會給你整數值:
In [12]: it = iter(s)
In [13]: next(it)
Out[13]: 102
In [14]: for ele in s:
print(ele)
....:
102
111
111
在python2中,你只需要獲得每個角色。 因此,在代碼中迭代從encry.read()
返回的字節對象時,您將獲得整數值,因此ord(some_int)
顯然會失敗。
有一個詳盡的解釋文本與二進制數據 ,它解釋了python2和python3之間的區別,其中一個片段是:
作為這種二分法的一部分,您還需要小心打開文件。 除非您一直在使用Windows,否則在打開二進制文件時(例如,rb用於二進制讀取),您可能並不總是打擾添加b模式。 在Python 3下,二進制文件和文本文件明顯不同,互不兼容; 有關詳細信息,請參閱io模塊。 因此,您必須決定文件是用於二進制訪問(允許讀取和/或寫入二進制數據)還是文本訪問(允許讀取和/或寫入文本數據)。 您還應該使用io.open()來打開文件而不是內置的open()函數,因為io模塊從Python 2到3是一致的,而內置的open()函數則不是(在Python 3中它實際上是io.open())。
str和bytes的構造函數對於Python 2和3之間的相同參數具有不同的語義。在Python 2中將整數傳遞給字節將為您提供整數的字符串表示形式:
bytes(3) == '3'
。 但是在Python 3中,字節的整數參數將為您提供一個字節對象,只要指定的整數,填充空字節:bytes(3) == b'\\x00\\x00\\x00'
。 將bytes對象傳遞給str時,需要類似的擔心。 在Python 2中,您只需返回字節對象:str(b'3') == b'3'
。 但是在Python 3中,你得到了bytes對象的字符串表示形式:str(b'3') == "b'3'"
。最后,二進制數據的索引需要仔細處理(切片不需要任何特殊處理)。 在Python 2中,
b'123'[1] == b'2'
而在Python 3b'123'[1] == 50
。 因為二進制數據只是二進制數的集合,所以Python 3返回您索引的字節的整數值。 但是在Python 2中因為bytes == str,索引返回一個單項的字節切片。 這個六個項目有一個名為six.indexbytes()的函數,它將返回一個像Python 3中的整數:six.indexbytes(b'123',1)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.