zlib压缩

小场景:需要对传输的字节进行压缩传输 

解压缩的一席而基础知识介绍:

文件压缩主要是对二进制进行要说,主要看文件的信息熵的大小,然后对文件进行压缩和解压缩

Java8用的是gzib对字符串进行压缩和解压缩

在web项目中,服务器端将加密后的字符串返回给前端,前端再通过ajax请求将加密字符串发送给服务器端处理的时候,在http传输过程中会改变加密字符串的内容,导致服务器解压压缩字符串发生异常:

gzib压缩和解压缩的原理,先把字符串压缩成二进制byte[],压缩后的内容会再用base64编码变回base64字符串方便传输和存储数据库。
java.util.zip.ZipException: Not in GZIP format

解决方法:
在字符串压缩之后,将压缩后的字符串BASE64加密,在使用的时候先BASE64解密再解压即可。

Java使用org.apache.commons.codec.binary.Base64进行解压缩

python可以压缩字符串也可以压缩文件

压缩和解压的原理:
重复的东西简化掉,文件的重复的东西很高压缩之后就会很小,文件重复的东西不大,压缩之后也不会很大,这就是信息熵很大。

压缩速度快,压缩率低,压缩速度小,压缩率高,有缺点,有优点。

gzib压缩.woff 字体文件,压缩之后会增大,不会减小。

2.gzip的格式分析
gzip = gzip 头 + deflate 编码的实际内容 + gzip 尾

3. zlib库函数API分析
zlib = zlib 头 + deflate 编码的实际内容 + zlib 尾

主要的压缩算法(Zlib、Gzip)都以DEFLATE算法为底层算法。DEFLATE则再由两个算法构成:LZ77算法与哈夫曼编码(Huffman Coding)

目前压缩率最好的算法是zlib( rfc1950)和gzip( rfc1952),他们都使用deflate( rfc1951)为底层算法,zlib和gzip只不过是对deflate的一层封装,用了不同的校验算法,定义了不同的Header。因此两者在各方面的差距在理论上都不太大。

比如google开源的snappy,facebook开源的zstd,独立的lz4。这些算法通常压缩率会少个3-33%(甚至更多),但是压缩的速度能有几倍到几十倍的提升。

压缩字符串和元字符串对比测试: 

import zlib
import this
import os

def main():
    # python_zen = this.s  # 获取Python之禅的Unicode字符串
    python_zen ="123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910"  # 获取Python之禅的Unicode字符串
    com_bytes = zlib.compress(python_zen.encode('utf-8'))  # 编码为UTF-8格式的字节进行压缩
    print("开始:",com_bytes)
    size = len(com_bytes)
    print("字节数:",size)
    print("原始字节:",len(python_zen.encode()))
    decom_bytes = zlib.decompress(com_bytes)  # 将压缩的字节进行解压缩
    print("结束:",decom_bytes.decode('utf-8'))  # 将解压缩的字节进行UTF-8解码得到Unicode字符串


if __name__ == '__main__':
    main()

压缩后写入文件和未压缩比对: 

import this
import zlib


def main():
    # python_zen = this.s  # 获取字符
    python_zen = "123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910123456789101234567891012345678910"  # 获取字符
    with open('data.txt', 'wb') as f:  # 使用文件写入的上下文环境
        f.write(python_zen.encode('utf-8'))  # 写入未压缩的字节数据

    with open('com_data.txt', 'wb') as f:  # 使用文件写入上下文环境
        com_zen = zlib.compress(python_zen.encode('utf-8'))  # 将字符串编码并压缩
        f.write(com_zen)  # 写入压缩后的字节数据


if __name__ == '__main__':
    main()

你可能感兴趣的:(【python】,python)