繁体   English   中英

Python-3.x - 将bytearray的字符串表示形式转换回字符串

[英]Python-3.x - Converting a string representation of a bytearray back to a string

这里的背景故事有点冗长,但基本上我想采用像b'\\x04\\x0e\\x1d'这样的字符串并将其转换回bytearray。

我正在研究一次性填充的基本实现,其中我采用明文A和共享密钥B来生成符合等式A⊕B=C的密文C 然后我用公式C⊕B=A反转过程。

我已经发现了很多python3函数来将字符串编码为字节然后xor字节,如下所示:

def xor_strings(xs, ys):
    return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys)).encode()

xor_strings()调用然后返回一个bytearray:

print( xor_strings("foo", "bar"))

但是当我将它打印到屏幕上时,我所展示的实际上是一个字符串。 所以我假设python只是在bytearray上调用一些str()函数,我得到的内容如下所示:

b'\\x04\\x0e\\x1d'

这就是问题所在。 我想从该字符串创建一个新的bytearray。 通常我会在bytearray上调用decode() 但是如果输入'b'\\ x04 \\ x0e \\ x1d'作为输入,python会将其视为字符串,而不是字节数组!

如何将b'\\x04\\x0e\\x1d'这样的字符串作为用户输入并将其转换回bytearray?

如评论中所述,使用base64以文本形式发送二进制数据。

import base64

def xor_strings(xs, ys):
    return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys)).encode()

# ciphertext is bytes
ciphertext = xor_strings("foo", "bar")
# >>> b'\x04\x0e\x1d'

# ciphertext_b64 is *still* bytes, but only "safe" ones (in the printable ASCII range)
ciphertext_b64 = base64.encodebytes(ciphertext)
# >>> b'BA4d\n'

现在我们可以传输字节:

# ...we could interpret them as ASCII and print them somewhere
safe_string = ciphertext_b64.decode('ascii')
# >>> BA4d

# ...or write them to a file (or a network socket)
with open('/tmp/output', 'wb') as f:
    f.write(ciphertext_b64)

收件人可以通过以下方式检索原始邮件:

# ...reading bytes from a file (or a network socket)
with open('/tmp/output', 'rb') as f:
    ciphertext_b64_2 = f.read()

# ...or by reading bytes from a string
ciphertext_b64_2 = safe_string.encode('ascii')
# >>> b'BA4d\n'

# and finally decoding them into the original nessage
ciphertext_2 = base64.decodestring(ciphertext_b64_2)
# >>> b'\x04\x0e\x1d'

当然,在将字节写入文件或网络时,首先将它们编码为base64是多余的。 如果它是唯一的文件内容,您可以直接写/读密文。 只有当密文成为更高结构(JSON,XML,配置文件......)的一部分时,才需要将其编码为base64。

关于使用“解码”和“编码”一词的说明。

  • 字符串进行编码意味着将其从抽象含义(“字符列表”)转换为可存储表示(“字节列表”)。 此操作的确切结果取决于正在使用的字节编码。 例如:

    • ASCII编码将一个字符映射到一个字节(作为权衡,它不能映射Python字符串中可能存在的所有字符)。
    • UTF-8编码将一个字符映射到1-5个字节,具体取决于字符。
  • 解码字节数组意味着再次将其从“字节列表”转回“字符列表”。 这当然需要事先知道字节编码最初是什么。

上面的ciphertext_b64是一个字节列表,在Python控制台上表示为b'BA4d\\n'

它的字符串等效, safe_string ,当打印到控制台时看起来非常相似'BA4d\\n' ,因为base64是ASCII的子集。

然而,数据类型仍然根本不同。 不要让控制台输出欺骗你。

仅回答最后一个问题。

>>> type(b'\x04\x0e\x1d')
<class 'bytes'>
>>> bytearray(b'\x04\x0e\x1d')
bytearray(b'\x04\x0e\x1d')
>>> type(bytearray(b'\x04\x0e\x1d'))
<class 'bytearray'>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM