python - 需要类似字节的对象 / ord() 预期的长度为 1 的字符串,但找到了 int (python 3.6)
问题描述
我正在尝试使用: softScheck/tplink-smartplug
我陷入了错误循环。第一个的修复导致另一个,另一个的修复导致第一个。代码都可以在 git 链接的 tplink-smartplug.py 中找到。
cmd = "{\"system\":{\"set_relay_state\":{\"state\":0}}}"
sock_tcp.send(encrypt(cmd))
def encrypt(string):
key = 171
result = "\0\0\0\0"
for i in string:
a = key ^ ord(i)
key = a
result += chr(a)
return result
实际上,结果 = 'Ðòøÿ÷Õï¶Å Ôùðè·Ä°Ñ¥ÀâØ£òçöÔîÞ£Þ' 我得到了错误(在原始文件的第 92 行:sock_tcp.send(encrypt(cmd)):
需要一个类似字节的对象,而不是“str”
所以我也改变了函数调用:
sock_tcp.send(encrypt(cmd.encode('utf-8')))
我的错误也发生了变化:
ord() 预期长度为 1 的字符串,但找到 int
我了解 ord() 正在尝试做什么,并且我了解编码。但我不明白的是......如果我不能给编译器它想要的东西,我应该如何将此加密消息发送到我的智能插件?有解决办法吗?我很确定最初的 git 是用 Python 2 或更早版本编写的。所以也许我没有正确转换为 Python 3?
感谢您的阅读,感谢您的帮助。
解决方案
在 Python 2 中, 的结果encode
是一个str
字节字符串,它是一个 1 字节str
值的序列。所以,当你这样做时for i in string:
,每个i
都是一个str
,你必须打电话ord(i)
把它变成一个从 0 到 255 的数字。
在 Python 3 中, 的结果encode
是一个bytes
字节字符串,它是一个 1 字节整数的序列。所以当你这样做时for i in string:
,每个i
都已经是int
从 0 到 255 的一个,所以你不需要做任何事情来转换它。(而且,如果你无论如何都尝试这样做,你会得到TypeError
你所看到的。)
同时,您正在建立result
一个str
. 在 Python 2 中,这很好,但在 Python 3 中,这意味着它是 Unicode,而不是字节。因此,TypeError
您看到的另一个。
有关如何将 Python 2 字符串处理代码移植到 Python 3 的更多详细信息,您应该阅读移植指南,尤其是文本与二进制数据,如果您需要更多背景知识,可能还需要阅读Unicode HOWTO 。
您可以编写代码以在 Python 2 和 3 中以相同方式工作的一种方法是将 abytearray
用于两个值:
def encrypt(string):
key = 171
result = bytearray(b"\0\0\0\0")
for i in bytearray(string):
a = key ^ i
key = a
result.append(a)
return result
cmd = u"{\"system\":{\"set_relay_state\":{\"state\":0}}}"
sock_tcp.send(encrypt(cmd.encode('utf-8')))
注意u
前缀 on cmd
,它确保它即使在 Python 2 中也是 Unicode,而b
前缀 on result
,它确保它即使在 Python 3 中也是字节。虽然你知道cmd
它是纯 ASCII,但这样做可能更简单:
cmd = b"{\"system\":{\"set_relay_state\":{\"state\":0}}}"
sock_tcp.send(encrypt(cmd))
如果您不关心 Python 2,您可以只 forfor i in string:
而不将其转换为 a bytearray
,但您可能仍想使用一个 for result
。(能够append
直接对它进行 int 处理可以简化代码——而且它甚至更高效,这是一个很好的奖励。)
推荐阅读
- bash - !< 是什么意思?
- inno-setup - 我可以在 Inno Setup 中将 .isl 文件用于带有预处理器指令的消息吗?
- validation - 何时/何地在 FastAPI 中使用正文/路径/查询/字段?
- ansible - Ansible:检查提示值
- excel - EXCEL:将两个动态数组与多列组合
- x86 - 对 x86 保护模式内存布局感到困惑
- kubernetes - nginx-ingress 反向代理后端子路径
- php - 通过钩子在 WooCommerce 单个产品页面中显示自定义字段值
- python - 从同一个文件创建数据库和表的最佳方法是什么?
- javascript - 如何从本地 html 文件中获取服务器内容?