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

标签 python arrays string python-3.x

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

我正在开发一次性一密本的基本实现,其中我使用明文 A 和共享 key B 来生成密文 C 根据方程A⊕B=C。然后我用方程 C⊕B=A 反转该过程。

我已经找到了大量的 python3 函数来将字符串编码为字节,然后对字节进行异或,如下所示:

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

调用xor_strings()然后返回一个字节数组:

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

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

b'\x04\x0e\x1d'

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

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

最佳答案

正如评论中所讨论的,使用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'

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

但是数据类型仍然有根本的不同。不要让控制台输出欺骗您。

关于Python-3.x - 将字节数组的字符串表示形式转换回字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43873429/

相关文章:

ruby-on-rails - 顺序数组。数组的未定义方法 `order'。将数组转换为哈希?

Python导入内部差异

python - 如何使用 List Comprehension 将 Python 中的二维数组合并为一个字符串?

python - 在 Python 中导入 Statsmodel 时出错

javascript - JavaScript 中的美化函数

c - 包含字符串的结构体的初始化

linux - 如果位置 1 上的字符和在行中找到的字符串,则 grep 整行

python - 使用 ftplib 和多处理上传多个文件

ruby - 如何过滤数组中的元素?

php - 按两个值排序关联数组 PHP