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

Python-3.x-将bytearray的字符串表示形式转换回字符串,python,arrays,string,python-3.x,Python,Arrays,String,Python 3.x,这里的背景故事有点冗长,但基本上我想用一个字符串,比如b'\x04\x0e\x1d',把它放回字节数组 我正在研究一个一次性键盘的基本实现,在这里,我使用明文a和共享密钥B根据等式a生成密文C⊕B=C。然后,我用方程C来反转这个过程⊕B=A 我已经找到了很多python3函数,它们将字符串编码为字节,然后对字节进行异或运算,例如: def xor_strings(xs, ys): return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs

这里的背景故事有点冗长,但基本上我想用一个字符串,比如
b'\x04\x0e\x1d'
,把它放回字节数组

我正在研究一个一次性键盘的基本实现,在这里,我使用明文
a
和共享密钥
B
根据等式
a生成密文
C
⊕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\u strings()
然后返回bytearray:

print( xor_strings("foo", "bar"))
但是当我把它打印到屏幕上时,我看到的实际上是一个字符串。所以我假设python只是调用bytearray上的一些
str()
函数,我得到如下结果:

def xor_strings(xs, ys):
    return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(xs, ys)).encode()
b'\x04\x0e\x1d'

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


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

仅回答最后一个问题

>>> 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'>
>>类型(b'\x04\x0e\x1d')
>>>字节数组(b'\x04\x0e\x1d')
字节数组(b'\x04\x0e\x1d')
>>>类型(字节数组(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\u b64
是一个字节列表,在Python控制台上表示为
b'BA4d\n'

由于base64是ASCII的一个子集,因此当打印到控制台时,它的字符串等价物safe\u string看起来非常相似


但是,数据类型仍然存在根本的不同。不要让控制台输出欺骗你。

我有点困惑
b'\x04\x0e\x1d'
不是字符串,而是字节数组。或者您希望用户在文本框中输入“b'\x04\x0e\x1d'”?这不是向朋友发送字节的方式,至少我强烈反对这样做。对于这样的任务,请使用常见的传输编码(如base64)。No。发送base64;收件人可以轻松地复制和粘贴。这是一种弹性格式,几乎地球上的每个环境都可以将其解码回字节。Python具有实现此目的的能力。@Tomalak好吧,我现在确信您是正确的,base64是一条正确的道路。但是,即使这个问题很奇怪,我仍然很好奇你会如何从文本框中提取“b'\x04\x0e\x1d'”,并将其转换为bytearray。是否有一种简单/内置的方法?或者你基本上需要解析字符串并转换每个字节是的,我会编写一个循环,一次遍历字符串四个字符,然后将每个部分转换成一个数字,在运行时构建一个字节数组。基本上与base64解码器的功能相同,但base64正是为了这个目的而设计的,它解决了许多您甚至没有想到的问题,作为内置模块,它基本上是免费的。