使用Python对文件进行Xor加密/解密3 [英] Xor encryption/decryption of a file with Python 3

查看:777
本文介绍了使用Python对文件进行Xor加密/解密3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用Python 3使用xor加密/解密文件,我有一个在Python 2中可以正常工作的代码,但是当尝试将其适用于Python 3时,会给我一些我无法解决的错误。 / p>

此代码在Python 2.7中正常工作:

  from itertools import cycle 


def xore(data,key):
return''。(zip(ord) (data,cycle(key)))

with open('inputfile.jpg','rb')as encryption,open('outputfile.jpg','wb')as decrypt:
decrypt.write(xore(encrypt.read(),'anykey'))

错误当尝试在python 3中运行不变:

 追溯(最近的最后一次调用):
文件ask.py ,第8行,< module>
decrypt.write(xore(encrypt.read(),'anykey'))
文件ask.py,第5行,xore
return''.join(chr(ord (a,b)中的zip(数据,循环(key))中的(a)^ ord(b))
文件ask.py,第5行,< genexpr>
TypeError:ord()预期的字符串(),(b))for(a,b)in zip(data,cycle(key)的长度为1,但int发现

请是否有人可以解释并帮助我将此代码适应Python 3

解决方案

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



<$ p $ (数据,关键字):
return''。(zip,(key))中的(a,b) ))

如果没有$ $ c $,您将无法将加入的字符串写入outfile c> .encode(utf-8)这不会给你任何可用的输出,所以不知道你实际想要实现什么。



你可以看到你在Python中找到一个int字符串的索引:

  n [1]:s = b foo

在[2]中:s [0]
输出[2]:102#f

其中python2你得到str / char:

 在[1]中:s = bfoo
在[2 ]:s [0]
Out [2]:'f'

迭代或调用下一个还给你整数值:

 在[12]中:it = iter(s)
在[13 ]:next(it)
出[13]:102
在[14]中:对于ele中的ele:
print(ele)
....:
102
111
111

在python2中,您只需获取每个字符。所以在你的代码中迭代从 encrypt.read()返回的字节对象,你得到整数值,所以 ord(some_int) code>明显失败。



有一个彻底的解释文本与二进制数据,它解释了python2和python3之间的区别,其代码片段是:


作为这个二分法的一部分,您还需要小心打开文件。除非你在Windows上工作,否则打开一个二进制文件(例如,用于二进制读取的rb)有一个机会,你并不总是打扰添加b模式。
在Python 3下,二进制文件和文本文件清晰明了,相互不兼容;有关详细信息,请参阅io模块。因此,您必须决定是否将文件用于二进制访问(允许读取和/或写入二进制数据)或文本访问(允许读取和/或写入文本数据)。您还应该使用io.open()打开文件而不是内置的open()函数,因为io模块与Python 2至3是一致的,而内置的open()函数不是(在Python 3中它实际上是io.open())。



str和bytes的构造函数在Python 2和amp之间的相同参数具有不同的语义。 3.在Python 2中传递一个整数到字节将给出整数的字符串表示形式: bytes(3)=='3'。但是在Python 3中,字节的整数参数会给你一个字节对象,只要指定的整数,填满空字节: bytes(3)== b'\x00\x00\ X00' 。当将一个字节对象传递给str时,同样的担心是必要的。在Python 2中,您只需得到字节对象: str(b'3')== b'3'。但是在Python 3中,您可以获得字节对象的字符串表示形式: 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)。



I need to encrypt / decrypt a file using xor with Python 3, I have a code that works fine in Python 2, but when trying to adapt it to Python 3, gives me some errors that I can't solve.

This code works fine in 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'))

The error when trying to run unchanged in 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

Please if someone could explain and help me adapt this code to Python 3.

解决方案

a is already an int so you would need to remove the call to ord(a):

def xore(data, key):
    return ''.join(chr(a ^ ord(b)) for (a, b) in zip(data, cycle(key)))

You will not be able to write the joined string to your outfile without a .encode("utf-8") which will not give you any usable output so not sure what you are actually trying to achieve.

You can see when you index a byte string you get an int in python3:

n [1]: s = b"foo"

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

Where in python2 you get the str/char:

In [1]: s = b"foo"
In [2]: s[0]
Out[2]: 'f'

iterating or calling next also gives you the integer value:

In [12]: it = iter(s)   
In [13]: next(it)
Out[13]: 102
In [14]: for ele in s:
         print(ele)
   ....:     
102
111
111

In python2 you would just get each character. So in your code as you iterate over the bytes objects returned from encry.read() you are getting the integer values so ord(some_int) obviously fails.

There is a thorough explanation text-versus-binary-data which explains the differences between python2 and python3 a snippet of which is:

As part of this dichotomy you also need to be careful about opening files. Unless you have been working on Windows, there is a chance you have not always bothered to add the b mode when opening a binary file (e.g., rb for binary reading). Under Python 3, binary files and text files are clearly distinct and mutually incompatible; see the io module for details. Therefore, you must make a decision of whether a file will be used for binary access (allowing to read and/or write binary data) or text access (allowing to read and/or write text data). You should also use io.open() for opening files instead of the built-in open() function as the io module is consistent from Python 2 to 3 while the built-in open() function is not (in Python 3 it’s actually io.open()).

The constructors of both str and bytes have different semantics for the same arguments between Python 2 & 3. Passing an integer to bytes in Python 2 will give you the string representation of the integer: bytes(3) == '3'. But in Python 3, an integer argument to bytes will give you a bytes object as long as the integer specified, filled with null bytes: bytes(3) == b'\x00\x00\x00'. A similar worry is necessary when passing a bytes object to str. In Python 2 you just get the bytes object back: str(b'3') == b'3'. But in Python 3 you get the string representation of the bytes object: str(b'3') == "b'3'".

Finally, the indexing of binary data requires careful handling (slicing does not require any special handling). In Python 2, b'123'[1] == b'2' while in Python 3 b'123'[1] == 50. Because binary data is simply a collection of binary numbers, Python 3 returns the integer value for the byte you index on. But in Python 2 because bytes == str, indexing returns a one-item slice of bytes. The six project has a function named six.indexbytes() which will return an integer like in Python 3: six.indexbytes(b'123', 1).

这篇关于使用Python对文件进行Xor加密/解密3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆