AttributeError:'bytes' object has no attribute 'encode'
AttributeError:'bytes' object has no attribute 'encode'
尝试将代码从 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' object has no attribute 'encode'
如果我删除 .encode("utf-8")
,错误是 "can't concat str to bytes"。显然 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: can't concat str to bytes
然而,奇怪的是,如果我只是尝试这个部分。 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'>
由于AES.new
的第一个参数是bytes/bytearray/memoryview,而我假设text
已经是bytes
类型,那么我们只需要转换pad部分从 unicode
到 bytes
.
text = text + (pad * chr(pad)).encode("utf-8")
为了更加安全,您可以在与 pad 连接之前有条件地编码 text
。
if not isinstance(text, bytes):
text = text.encode('utf-8')
如果您不知道类字符串对象是 Python 2 字符串(字节)还是 Python 3 字符串(unicode)。你可以有一个通用转换器。
Python3 shell:
>>> 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'
On Python 2 这两个表达式的计算结果为 True
:type("hello") == bytes
和 type("hello") == str
。 type(u"hello") == str
的计算结果为 False
,而 type(u"hello") == unicode
为 True
。
上Python3 type("hello") == bytes
是False
,type("hello") == str
是True
。 type("hello") == unicode
引发 NameError
异常,因为 unicode
未在 3.
上定义
Python 2 shell:
>>> to_bytes(u"hello")
'hello'
>>> to_bytes("hello")
'hello'
感谢@Todd,他解决了问题。
(pad * chr(pad))
是字节,而问题在于 aesEncrypt(text, secKey)
。它被调用了两次 text
,第一次是 str
,第二次是 bytes
。
解决方法是确保输入text
是str
类型。
尝试将代码从 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' object has no attribute 'encode'
如果我删除 .encode("utf-8")
,错误是 "can't concat str to bytes"。显然 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: can't concat str to bytes
然而,奇怪的是,如果我只是尝试这个部分。 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'>
由于AES.new
的第一个参数是bytes/bytearray/memoryview,而我假设text
已经是bytes
类型,那么我们只需要转换pad部分从 unicode
到 bytes
.
text = text + (pad * chr(pad)).encode("utf-8")
为了更加安全,您可以在与 pad 连接之前有条件地编码 text
。
if not isinstance(text, bytes):
text = text.encode('utf-8')
如果您不知道类字符串对象是 Python 2 字符串(字节)还是 Python 3 字符串(unicode)。你可以有一个通用转换器。
Python3 shell:
>>> 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'
On Python 2 这两个表达式的计算结果为 True
:type("hello") == bytes
和 type("hello") == str
。 type(u"hello") == str
的计算结果为 False
,而 type(u"hello") == unicode
为 True
。
上Python3 type("hello") == bytes
是False
,type("hello") == str
是True
。 type("hello") == unicode
引发 NameError
异常,因为 unicode
未在 3.
Python 2 shell:
>>> to_bytes(u"hello")
'hello'
>>> to_bytes("hello")
'hello'
感谢@Todd,他解决了问题。
(pad * chr(pad))
是字节,而问题在于 aesEncrypt(text, secKey)
。它被调用了两次 text
,第一次是 str
,第二次是 bytes
。
解决方法是确保输入text
是str
类型。