pyaes和Python 3中字节和str之间的关系?
我试图在Python3中使用pyaes()来使用pyaes加密和解密文本。当我加密文本时,我给pyaes一个pyaes和Python 3中字节和str之间的关系?,python,encryption,Python,Encryption,我试图在Python3中使用pyaes()来使用pyaes加密和解密文本。当我加密文本时,我给pyaes一个str值,即 plaintext = 'plain text' key = os.urandom(16) aes = pyaes.AESModeOfOperationCTR(key) ciphertext = aes.encrypt(plaintext) 但当我解密时,我会返回一个bytes类型: aes = pyaes.AESModeOfOperationCTR(key) decryp
str
值,即
plaintext = 'plain text'
key = os.urandom(16)
aes = pyaes.AESModeOfOperationCTR(key)
ciphertext = aes.encrypt(plaintext)
但当我解密时,我会返回一个bytes
类型:
aes = pyaes.AESModeOfOperationCTR(key)
decrypted_plaintext = aes.decrypt(ciphertext)
打印解密的\u明文
会产生以下输出,其中似乎包含原始文本:
b'plain text'
但这并不完全相同;一个是str
另一个是bytes
:
plaintext == decrypted_plaintext # False
我正在努力理解字节
与Python 3内部表示的str
之间的关系。如何将bytes
类型转换为str
以获取明文
我已经确认,在pyaes自述页面上运行示例也存在同样的问题。我猜这与编码有关。解密的\u明文。decode()将为您提供一个
str
,这很可能是您想要的。bytes
对象是未指定编码的原始字节字符串。要将其转换为str
,您必须告诉Python使用decode()
默认为UTF-8,但您可以告诉它使用哪种编码
我只是浏览了一下,没有看到任何特定于编码的内容,因此解密字符串的编码应该与加密字符串的编码匹配。在Python 3
str
中,type表示unicode格式的字符串。它由相对抽象的代码点组成,即编码字符的数字。
有几种方法可以将这些代码点转换(编码)为实际字节,称为“编码”。utf-8和utf-16是一些允许编码unicode字符的编码
请注意,某些编码(如ASCII)不允许对unicode字符进行编码
在Python中对str
字符串进行编码时,将获得类型为bytes
的字节列表。然后,您可以解码此字节列表以获得str
字符串
需要记住的一点是,您必须指定编码来编码str
字符串,并且必须知道字节的编码才能对其进行解码。如果不指定编码,Python将尝试使用其默认编码进行编码和解码,您可以获得“随机”结果
在您特定的情况下,差异是不可见的,因为字符串的所有字符都是ASCII字符,幸运的是,unicode的128个前代码点与ASCII表匹配
尝试在字符串中引入一些“注释”字符(如é、ç或Ë),您将看到不同之处
现在,pyaes不加密/解密unicode代码点,而是对字节进行加密/解密。
因此,您必须对加密的字符串进行编码,并且必须知道用于解码解密字符串的编码
Python文档中的更多信息:
对于所有其他文件,这可以帮助您:如果解密。解码('utf-8')==明文:
# A 256 bit (32 byte) key
key = b"This_key_for_demo_purposes_only!"
aes = pyaes.AESModeOfOperationCTR(key)
plaintext = "Text may be any length you wish, no padding is required"
ciphertext = aes.encrypt(plaintext)
# '''\xb6\x99\x10=\xa4\x96\x88\xd1\x89\x1co\xe6\x1d\xef;\x11\x03\xe3\xee
# \xa9V?wY\xbfe\xcdO\xe3\xdf\x9dV\x19\xe5\x8dk\x9fh\xb87>\xdb\xa3\xd6
# \x86\xf4\xbd\xb0\x97\xf1\t\x02\xe9 \xed'''
print (repr(ciphertext))
# The counter mode of operation maintains state, so decryption requires
# a new instance be created
aes = pyaes.AESModeOfOperationCTR(key)
decrypted = aes.decrypt(ciphertext)
print(type(decrypted))
print(type(plaintext))
# True
if decrypted.decode('utf-8') == plaintext:
print(plaintext)
print(True)
print(decrypted.decode('utf-8'))
# '''WZ\x844\x02\xbfoY\x1f\x12\xa6\xce\x03\x82Ei)\xf6\x97mX\x86\xe3\x9d
# _1\xdd\xbd\x87\xb5\xccEM_4\x01$\xa6\x81\x0b\xd5\x04\xd7Al\x07\xe5
# \xb2\x0e\\\x0f\x00\x13,\x07'''
print (repr(ciphertext))
对于字节
(数据)和str
(文本)之间的差异:对于字节
和str
:ta之间的转换,认为这可能是编码方面的问题。我真的需要一些ASCII格式的密文,这样我就可以轻松地存储、检索和传输它。我最终得到了这样的结果:utf8=plaintext.encode('utf-8')
,cipherbytes=encrypt(utf8)
,cipherb64=base64.encode(cipherbytes)
,cipherutf8=cipherb64.decode('utf-8')
。而解密则相反。