使用 Python 3 编码和解码二进制数据以包含到 JSON 中

The*_*aan 8 python base64 encoding json binary-data

我需要决定一个将二进制元素包含到消息对象中的模式,以便可以在接收端再次解码它(在我的情况下是 Rabbit MQ / AMQP 队列上的消费者)。

我决定不使用 JSON 进行多部分 MIME 编码,主要是因为它看起来像是使用雷神之锤来推图钉。我决定不手动连接各个部分(二进制和 JSON 连接在一起),主要是因为每次出现新需求时都需要进行整体重新设计。在其中一个字段中编码二进制文件的 JSON 似乎是一种优雅的解决方案。

我看似可行的解决方案(通过比较发送和接收数据的 MD5 和来确认)解决方案执行以下操作:

def json_serialiser(byte_obj):
    if isinstance(byte_obj, (bytes, bytearray)):
        # File Bytes to Base64 Bytes then to String
        return base64.b64encode(byte_obj).decode('utf-8')
    raise ValueError('No encoding handler for data type ' + type(byte_obj))


def make_msg(filename, filedata):
    d = {"filename": filename,
         "datalen": len(filedata),
         "data": filedata}
    return json.dumps(d, default=json_serialiser)
Run Code Online (Sandbox Code Playgroud)

在接收端我只需这样做:

def parse_json(msg):
    d = json.loads(msg)
    data = d.pop('data')
    return base64.b64decode(data), d


def file_callback(ch, method, properties, body):
    filedata, fileinfo = parse_json(body)
    print('File Name:', fileinfo.get("filename"))
    print('Received File Size', len(filedata))
Run Code Online (Sandbox Code Playgroud)

我的谷歌搜索让我无法确认我所做的事情是否真的有效。我特别关心从二进制数据生成字符串以包含到 JSON 中的行是否正确,例如行 return base64.b64encode(byte_obj).decode('utf-8')

似乎我可以采取一种捷径,将解码回二进制数据,因为该方法base64.b64decode()将 UTF-8 数据视为 ASCII - 正如人们所期望的那样,它来自base64.b64encode()...的输出这在所有情况下都是有效的假设吗?

最令我惊讶的是无法在网上找到任何这样做的示例。也许我的谷歌耐心还在休假!

sna*_*erb 9

文档确认您的方法没问题。

base64.b64encode(byte_obj).decode('utf-8')是正确的 - base64.b64encode需要字节作为输入:

使用 Base64 对类似字节的对象 s 进行编码并返回编码后的字节。

但是base64.b64decode 接受字节或 ascii 字符串:

解码 Base64 编码的类似字节的对象或 ASCII 字符串返回解码后的字节。

  • 使用“utf-8”或“latin-1”并不重要,因为两种编码都将 ascii 字符编码为相同的值,而 base64 仅使用 ascii。所以两者都可以。 (2认同)