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

2024-06-01 10:34:06 发布

您现在位置:Python中文网/ 问答频道 /正文

尝试将代码从python2导入Python3时,会出现此问题

    <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"),错误是“无法将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: 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'>

Tags: textlenbytestypeipythonutfclassencode
3条回答

如果您不知道stringlike对象是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'

在Python2上,这两个表达式的计算结果都是True:type("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外壳:

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

多亏了@Todd,他解决了这个问题。 (pad * chr(pad))是字节,而问题在于aesEncrypt(text, secKey)。第一次用text作为str调用它两次,第二次用bytes调用它

解决方案是确保输入textstr类型

由于AES.new的第一个参数是bytes/bytearray/memoryview,并且我假设text已经是bytes类型,那么我们只需要将焊盘部分从unicode转换为bytes

text = text + (pad * chr(pad)).encode("utf-8")

为了更加安全,您可以在与pad连接之前有条件地对text进行编码

if not isinstance(text, bytes):
    text = text.encode('utf-8')

相关问题 更多 >