Python中对二进制文件编码

JSON是一种简单方便的数据交换协议,但一般情况下JSON只能对字符串,整型和浮点型数据编码传输,一般的文本文件可以通转换为过字符串传输,而二进制的文件则不能直接传输,在这种情况下就需要对二进制文件进行编码,转换成适合JSON传输的格式,在这里采用base64的编码。

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email,email via MIME, 在XML中存储复杂数据。
转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6(因为)个bit,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。

如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。

Python 对二进制文件Base64编码

Python的base54库可以直接对二进制文件编码和解码,一个简单的例子如下:

import base64

fin = open("platinum_firebird.out", "rb")
fout = open("based.txt", "wb")

base64.encode(fin, fout)
fin.close()
fout.close()

fin = open("based.txt", "rb")
fout = open("out.out", "wb")
base64.decode(fin, fout)
fin.close()
fout.close()

base64中的encodedecode函数直接可以对文件进行编码和解码。

文件编码为字符串

在通过JSON传输时,需要将文件转化为字符串str,需要用到b64encodeb64decode两个函数。

import base64
import json

with open("platinum_firebird.out", "rb") as fin:
    coded = base64.b64encode(fin.read()).decode()
send = json.dumps({"file": coded})

receive = json.loads(send)['file']

decoded = base64.b64decode(receive)
with open("out.out", "wb") as fout:
    fout.write(decoded)

需要说明的是base64.b64encode的结果是bytes类型,bytes是不能直接被json序列化的,需要通过decode转化为str类型,这个主要是python3对bytesstr区别对待造成的。

通过上面的例子,我们已经可以实现文件的JSON的传输。

GZIP压缩

这里举例用的文件大小是482396, base64编码并JSON化之后是643208,可以看到base64之后文件变大了,这是意料之中的,为了节省网络带宽,我们可以对文件压缩之后再编码,举例程序如下:

import base64
import json
import gzip

with open("platinum_firebird.out", "rb") as fin:
    coded = base64.b64encode(gzip.compress(fin.read())).decode()
send = json.dumps({"file": coded})
print(len(send))

receive = json.loads(send)['file']

decoded = gzip.decompress(base64.b64decode(receive))
with open("out.out", "wb") as fout:
    fout.write(decoded)

压缩之后编码最终JSON化之后字符串减小到115508, 只有原来的1/5左右大小,可以看到,压缩效果还是非常明显的,不过这个和原始文件的内容有关。

原始文件大小直接编码结果压缩之后编码结果
482396643208115508

本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

相关文章

发表新评论