首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Python 3对文件进行异或加密/解密

用Python 3对文件进行异或加密/解密
EN

Stack Overflow用户
提问于 2015-09-19 19:08:22
回答 1查看 6K关注 0票数 3

我需要用Python 3使用xor加密/解密一个文件,我有一个在Python 2中运行良好的代码,但是当试图将它修改到Python 3时,会给我一些我无法解决的错误。

这段代码在Python2.7中运行得很好:

代码语言:javascript
运行
复制
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中尝试不更改地运行时出错:

代码语言:javascript
运行
复制
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,请允许我这样做。

EN

回答 1

Stack Overflow用户

发布于 2015-09-19 19:32:33

a已经是一个int,所以您需要删除对ord(a)的调用。

代码语言:javascript
运行
复制
def xore(data, key):
    return ''.join(chr(a ^ ord(b)) for (a, b) in zip(data, cycle(key)))

如果没有.encode("utf-8"),您将无法将连接字符串写入到外部文件,这将不会为您提供任何可用的输出,因此无法确定您实际要实现的是什么。

您可以看到,当您索引字节字符串时,可以在python3中得到一个int:

代码语言:javascript
运行
复制
n [1]: s = b"foo"

In [2]: s[0]
Out[2]: 102  # f

在python2中哪里可以得到str/char:

代码语言:javascript
运行
复制
In [1]: s = b"foo"
In [2]: s[0]
Out[2]: 'f'

迭代或调用next还会给出整数值:

代码语言:javascript
运行
复制
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模块从Python2到3是一致的,而内置的open()函数则不是(在Python3中,它实际上是io.open())。 str和字节的构造函数对于Python2& 3之间的相同参数具有不同的语义。将一个整数传递给Python2中的字节将给出整数:bytes(3) == '3'的字符串表示形式。但是在Python3中,对字节的整数参数将给出一个字节对象,只要指定的整数被空字节填充:bytes(3) == b'\x00\x00\x00'。在将字节对象传递给str时,也需要类似的担心。在Python2中,只需要返回字节对象:str(b'3') == b'3'。但是在Python3中,您可以得到字节对象的字符串表示:str(b'3') == "b'3'"。 最后,二进制数据的索引需要小心处理(切片不需要任何特殊处理)。Python 2中的b'123'[1] == b'2'中的,Python 3中的中的由于二进制数据只是二进制数字的集合,Python3返回您索引的字节的整数值。但是在Python2中,因为字节== str,索引返回一个字节的单项切片。**这六个项目有一个名为six.indexbytes()的函数,它将返回一个整数,如Python3: six.indexbytes(b'123',1)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32672181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档