将字节字符串转换为 base64 编码的字符串(输出不是字节字符串)

Convert byte string to base64-encoded string (output not being a byte string)

我想知道是否可以将我从读取文件中获得的字节字符串转换为字符串(所以 type(output) == str)。到目前为止,我在 Google 上找到的所有答案都是像 How do you base-64 encode a PNG image for use in a data-uri in a CSS file? 这样的答案,它看起来确实适用于 python 2(如果我没记错的话,字符串是字节字符串),但在 python 3.4 中不再起作用。

我想将此生成的字节字符串转换为普通字符串的原因是我想使用此 base64 编码的数据存储在 JSON 对象中,但我不断收到类似于以下内容的错误:

TypeError: b'Zm9v' is not JSON serializable

这里有一个最简单的错误示例:

import base64
import json
data = b'foo'
myObj = [base64.b64encode(data)]
json_str = json.dumps(myObj)

所以我的问题是:有没有办法将这个 bytes 类型的对象转换为 str 类型的对象,同时仍然保持 base64 编码(所以在这个例子中,我想要结果是 ["Zm9v"]。这可能吗?

尝试

data = b'foo'.decode('UTF-8')

而不是

data = b'foo'

将其转换为字符串。

对我有用的是将 b64encode 行更改为:

myObj = [base64.b64encode(data).decode('ascii')]

这在中有解释:

base64 has been intentionally classified as a binary transform.... It was a design decision in Python 3 to force the separation of bytes and text and prohibit implicit transformations.

接受的答案对我不起作用(Python 3.9)并给出错误:

Traceback (most recent call last):
  File "/tmp/x.py", line 4, in <module>
    myObj = [base64.b64encode(data)]
  File "/usr/lib64/python3.9/base64.py", line 58, in b64encode
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'

我找不到将字节转换为 urlsafe b64 编码字符串的合适答案,因此请在此处发布我的解决方案。

假设您有一个输入:

mystring = b'\xab\x8c\xd3\x1fw\xbb\xaaz\xef\x0e\xcb|\xf0\xc3\xdfx=\x16\xeew7\xffU\ri/#\xcf0\x8a2\xa0'

编码为base64

from base64 import b64encode # or urlsafe_b64decode
b64_mystring = b64encode(mystring) 

这给出:b'q4zTH3e7qnrvDst88MPfeD0W7nc3/1UNaS8jzzCKMqA=' 仍然需要解码,因为字节不是 JSON 可序列化的。

import requests
requests.get("https://google.com", json={"this": b64_mystring})

# raises "TypeError: Object of type bytes is not JSON serializable"

因此我们使用:

from base64 import b64encode
b64_mystring = b64encode(mystring).decode("utf-8")

这给了我们:q4zTH3e7qnrvDst88MPfeD0W7nc3/1UNaS8jzzCKMqA=

现在 JSON 可序列化(使用 json.dumps)。

试试这个:

def bytes_to_base64_string(value: bytes) -> str:
   import base64
   return base64.b64encode(value).decode('ASCII')

经常有一种误解,尤其是来自 Java 世界的人。 bytes.decode('ASCII') 实际上是将字节编码为字符串,而不是对其进行解码。