AttributeError:'bytes'对象没有属性'encode'

时间:2020-02-24 02:50:44

标签: python python-2to3

尝试将代码从python2导入到python 3并发生此问题

    <ipython-input-53-e9f33b00348a> in aesEncrypt(text, secKey)
     43 def aesEncrypt(text, secKey):
     44     pad = 16 - len(text) % 16
---> 45     text = text.encode("utf-8") + (pad * chr(pad)).encode("utf-8")
     46     encryptor = AES.new(secKey, 2, '0102030405060708')
     47     ciphertext = encryptor.encrypt(text)

AttributeError:“ bytes”对象没有属性“ encode”

如果我删除.encode("utf-8"),则错误是“无法将str连接到字节”。显然pad*chr(pad)似乎是一个字节字符串。它不能使用encode()

    <ipython-input-65-9e84e1f3dd26> in aesEncrypt(text, secKey)
     43 def aesEncrypt(text, secKey):
     44     pad = 16 - len(text) % 16
---> 45     text = text.encode("utf-8") + (pad * chr(pad))
     46     encryptor = AES.new(secKey, 2, '0102030405060708')
     47     ciphertext = encryptor.encrypt(text)

TypeError:无法将str连接为字节

但是,奇怪的是,如果我只是尝试一下。 encode()可以正常工作。

text = { 'username': '', 'password': '', 'rememberLogin': 'true' }
text=json.dumps(text)
print(text)
pad = 16 - len(text) % 16 
print(type(text))
text = text + pad * chr(pad) 
print(type(pad * chr(pad)))
print(type(text))
text = text.encode("utf-8") + (pad * chr(pad)).encode("utf-8") 
print(type(text))

{"username": "", "password": "", "rememberLogin": "true"}
<class 'str'>
<class 'str'>
<class 'str'>
<class 'bytes'>

3 个答案:

答案 0 :(得分:0)

由于AES.new的第一个参数是bytes / bytearray / memoryview,并且我假设text已经是bytes类型,所以我们只需要转换{ {1}}至unicode

bytes

为了更加安全,您可以在与pad串联之前对text = text + (pad * chr(pad)).encode("utf-8") 进行有条件的编码。

text

答案 1 :(得分:0)

如果您不知道类似字符串的对象是Python 2字符串(字节)还是Python 3字符串(unicode)。您可以有一个通用转换器。

Python3外壳程序:

>>> def to_bytes(s):
...     if type(s) is bytes:
...         return s
...     elif type(s) is str or (sys.version_info[0] < 3 and type(s) is unicode):
...         return codecs.encode(s, 'utf-8')
...     else:
...         raise TypeError("Expected bytes or string, but got %s." % type(s))
...         
>>> to_bytes("hello")
b'hello'
>>> to_bytes("hello".encode('utf-8'))
b'hello'

在Python 2上,这两个表达式的求值均为Truetype("hello") == bytestype("hello") == str。并且type(u"hello") == str的值为False,而type(u"hello") == unicodeTrue

在Python 3上,type("hello") == bytesFalse,而type("hello") == strTrue。并且type("hello") == unicode引发NameError异常,因为unicode未在3上定义。

Python 2 shell:

>>> to_bytes(u"hello")
'hello'
>>> to_bytes("hello")
'hello'

答案 2 :(得分:0)

感谢@Todd,他解决了问题。 (pad * chr(pad))是字节,而aesEncrypt(text, secKey)存在问题。第一次被text称为str两次,而第二次称为bytes了。

解决方案是确保输入text的类型为str