簡體   English   中英

Xor使用Python 3加密/解密文件

[英]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 3 b'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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM