【问题标题】:Python - concatenating byte to string cutting off some bytes in stringPython - 将字节连接到字符串切断字符串中的一些字节
【发布时间】:2016-09-23 17:27:06
【问题描述】:

我正在尝试使用带有 AES 密码的 Python 来解密图像文件。我们得到了一个 15 字节的密钥,我们的工作是解密运行到第一个字节的图像。

到目前为止,我所拥有的是:

fifteenbytes = b'\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c'

for i in range(0, 256):
    ipack = pack('B', i)

    key = ipack + fifteenbytes

我希望我会得到类似这样的密钥:

\x00\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c

对于迭代 0 - 255,但我最终得到:

b'\x00~\x15\x16(\xae\xd2\xa6\xab\xf7\x15\x88\t\xcfO<'

或有时会退出字符和 ascii 值,例如:

b'\t~\x15\x16(\xae\xd2\xa6\xab\xf7\x15\x88\t\xcfO<'
b'%~\x15\x16(\xae\xd2\xa6\xab\xf7\x15\x88\t\xcfO<'

谁能解释一下为什么会这样?

【问题讨论】:

  • 这是正常。 Python 字节对象将尽可能使用可打印的 ASCII 字符而不是使用\xhh 转义序列来显示。 这里没有数据丢失,您只是在查看偏向可读文本的调试输出。
  • 例如,7E 字节是 ASCII 标准中的 ~ 字符,由于这是一个可打印字符,repr() 输出使用 ~ 而不是 \x7E。当您的数据主要是文本时,这很有帮助,因为您不必手动将字节转换为 ASCII。
  • @MartijnPieters,我明白了,谢谢!那么这是否意味着如果我使用 7E 或 ~ 输入密码的密钥,它会给我相同的输出?
  • 完全正确; b'~' == b'\x7e'\xhh 符号只是定义字节值的语法,也可以用~ 指定。

标签: python byte aes pycrypto


【解决方案1】:

您得到了正确的输出,但您似乎对 repr() 输出的 bytes 值感到困惑。

Python 为您提供了一个可以安全地复制并粘贴回 Python 会话的值。这有助于调试。此显示在可能的情况下使用 ASCII 可打印文本来表示该值,但该值可以与所显示的内容完全相同。

您的预期值 b'\x00\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c' 包含几个可打印的 ASCII 字符,因此 Python 显示这些字符而不是 \xhh 字节值:

>>> output = b'\x00\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c'
>>> output 
b'\x00~\x15\x16(\xae\xd2\xa6\xab\xf7\x15\x88\t\xcfO<'
>>> output == b'\x00\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c'
True

字节串仍然是 16 字节长:

>>> len(output)
16

~ 是 ASCII 码点 126,或十六进制的 0x7E:

>>> output[1]
126
>>> hex(output[1])
'0x7e'

这同样适用于\x28(\x09\t(制表符转义序列)、\x4fO,以及\x3c&lt;

\xhh 转义序列只是bytes 对象文字中的符号,用于定义给定的字节值,但您可以使用~ 生成完全相同的值。 \t 同上,您可以表示与 \x09 相同的值,但 Python 在显示表示时更喜欢使用 \t 序列。

【讨论】:

    猜你喜欢
    • 2021-03-27
    • 2020-09-10
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 2016-03-28
    • 2021-07-20
    相关资源
    最近更新 更多