编码和解码二进制数据以包含到 JSON 和 Python 3
Encoding and decoding binary data for inclusion into JSON with Python 3
我需要决定将二进制元素包含到消息对象中的模式,以便它可以在接收端再次解码(在我的情况下,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耐心还在放假吧!
文档确认您的方法是正确的。
base64.b64encode(byte_obj).decode('utf-8')
是正确的 - base64.b64encode requires 字节作为输入:
Encode the bytes-like object s using Base64 and return the encoded bytes.
然而 base64.b64decode
accepts 字节或 ascii 字符串:
Decode the Base64 encoded bytes-like object or ASCII string s and return the decoded bytes.
我需要决定将二进制元素包含到消息对象中的模式,以便它可以在接收端再次解码(在我的情况下,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耐心还在放假吧!
文档确认您的方法是正确的。
base64.b64encode(byte_obj).decode('utf-8')
是正确的 - base64.b64encode requires 字节作为输入:
Encode the bytes-like object s using Base64 and return the encoded bytes.
然而 base64.b64decode
accepts 字节或 ascii 字符串:
Decode the Base64 encoded bytes-like object or ASCII string s and return the decoded bytes.