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

时间:2018-12-27 09:47:20

标签: python json encoding base64 binary-data

我需要确定一种将二进制元素包含到消息对象中的架构,以便可以在接收端再次对其进行解码(在我的情况下,是Rabbit MQ / AMQP队列上的使用者)。

我决定反对通过JSON进行多部分MIME编码,主要是因为这似乎是使用Thor的锤子来插入图钉。我决定不手动连接零件(二进制文件和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)

在接收端,我只是这样做:

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

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

似乎base64.b64decode()方法处理UTF-8数据时,好像能够处理ASCII码一样,它可以解码回二进制数据,这似乎是捷径-正如人们所期望的那样,它来自base64.b64encode()的输出...但这在所有情况下都是有效的假设吗?

最令我惊讶的是,我无法在网上找到任何这样做的例子。也许我的Google耐心还在度假!

1 个答案:

答案 0 :(得分:2)

文档确认您的方法还可以。

base64.b64encode(byte_obj).decode('utf-8')是正确的-base64.b64编码requires个字节作为输入:

  

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

但是base64.b64decode accepts个字节或一个ascii字符串:

  

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