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

时间:2017-05-09 15:05:06

标签: python arrays string python-3.x

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

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

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

C⊕B=A

调用def xor_strings(xs, ys): return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys)).encode() 然后返回一个bytearray:

xor_strings()

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

str()

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

如何将decode()之类的字符串作为用户输入并将其强制转换为bytearray?

2 个答案:

答案 0 :(得分:2)

如评论中所述,使用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。

使用单词" decode"和"编码"。

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

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

上面的

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

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

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

答案 1 :(得分:1)

仅回答最后一个问题。

>>> 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'>