GZIP文件格式解析和Inflate静态Huffman解压缩

2024-05-02 21:44

本文主要是介绍GZIP文件格式解析和Inflate静态Huffman解压缩,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GZIP是封装了Deflate压缩的格式文件;Deflate使用了无压缩、Huffman+LZ77进行压缩;解压是Inflate,Huffman包括静态Huffman压缩和动态Huffman压缩两种模式。

Java语言实现了GZIP格式解析、Inflate的静态Huffman解压缩、CRC32校验 算法。

gzip文件格式解析代码

	    BinaryInputStream bis = new BinaryInputStream(bytes); // 二进制字节流读取类Header header = new Header();  // 读取GZIP headerheader.ID1 = bis.ReadUInt8();  // GZIP ID1header.ID2 = bis.ReadUInt8();  // GzIP ID2header.CM = bis.ReadUInt8();  header.Flag = bis.ReadUInt8();header.Time = bis.ReadUnix32TimeStamp(); header.Xfl = bis.ReadUInt8();header.OS = bis.ReadUInt8();gzip.header = header;Console.printlnf("ID=%xb%xb", header.ID1, header.ID2); // 打印Console.printlnf("CM=%xb", header.CM);Console.printlnf("Flag=%xb", header.Flag);Console.printlnf("MTime=%S", header.Time);Console.printlnf("XFL=%xb", header.Xfl);Console.printlnf("OS=%xb", header.OS);if ( (header.Flag & 0b00001000) != 0) {  // 如果标志位是文件名String filename = bis.ReadCString(); // 读取字节流until 0->char[]->stringConsole.printlnf("filename=%S", filename);}else // 其他待实现throw new java.lang.IllegalArgumentException(header.Flag +"");byte[] result ; // 解压后的字节int data_len ;  // 解压前数据长度int crc;        // 程序计算解压后的CRC32(见上篇文章)if (header.CM == 8) { // deflate data_len = bytes.length - bis.GetPosition() - 8;			byte[] data = bis.ReadBytes(data_len); // 解压缩前数据	result = Deflate.uncompress(data);  // 解压缩,返回解压后字节流crc = CRC.CRC32(result); // 计算循环冗余码}else // 待实现throw new java.lang.IllegalArgumentException(header.CM +""); gzip.crc = bis.ReadUInt32(); // gzip文件自身存储的crc32值gzip.isize = bis.ReadInt32(); System.out.println("gzip crc="+ Long.toHexString(gzip.crc) +",calc-crc=" + Integer.toHexString( crc) );

解析结果如下:

显示了GZIP标志、压缩方法、压缩时间、原始文件名、操作系统类型、CRC校验值

GZIP中存储的CRC32值(gzip crc)==解压后计算的CRC32值(calc crc)。(0xa93145a2)

Inflate -静态Huffman解压缩:

	// 读取扩展Codeprivate static int ReadExtCode(BitsInputStream bis, int len) {bis.setOrder(BitOrder.LeftIsHigh);return bis.ReadBits(len);}// 读取距离private static int ReadDistance(BitsInputStream bis) {bis.setOrder(BitOrder.RightIsHigh);return bis.ReadBits(5);}// 读取Codeprivate static int ReadCode(BitsInputStream bis) {bis.setOrder(BitOrder.RightIsHigh);int code = bis.ReadBits(7);Integer value = FixHuffmanTable_7.get(code); // 7位长查表if (value == null) {int ext = bis.ReadBit();code = (code << 1 | ext);value = FixHuffmanTable_8.get(code); // 8位长查表if (value == null) {ext = bis.ReadBit();code = (code << 1 | ext);value = FixHuffmanTable_9.get(code); // 9位长查表if (value == -1)throw new java.lang.IllegalArgumentException(code + "");}}return value;}// Deflate解压缩public static byte[] uncompress(final byte[] _input) throws IOException {IntArrayBuffer baos = new IntArrayBuffer(); // 输出窗口// 位流读取类BitsInputStream bis = new BitsInputStream(_input);while (true) {int bFinal = bis.ReadBits(1); // 读取Deflate头,0 – 还有后续子块;1 – 该子块是最后一块。int bType = bis.ReadBits(2);  // 读取Deflate头,00 – 不压缩;01 – 静态Huffman编码压缩;10 – 动态Huffman编码压缩;11 – 保留if (bType == 0) { // 无压缩,未实现int len = bis.ReadBits(16);int nlen = bis.ReadBits(16);assert len + nlen == 65535;throw new java.lang.UnsupportedOperationException(bType + ""); }else if (bType == 1) { // fixed Huffmanwhile (true) {int value = ReadCode(bis); // 读取Huffman code// 根据literal范围判断if (value >= 0 && value <= 255) // literalbaos.Write(value);else if (value == 256) // 结束标志break ;else if (value >= 257 && value <= 285) { // 距离或长度int length = LengthExtraCodeLengthsTable.get(value);int bits = LengthExtraCodeBitsTable.get(value); if (bits != 0) {int ext =  ReadExtCode(bis, bits); // 读取长度length = length + ext; }value = ReadDistance(bis); // 读取距离int distance = DistanceExtraCodeLengthsTable.get(value);bits = DistanceExtraCodeBitsTable.get(value);if (bits != 0) {int ext =ReadExtCode(bis , bits); // 读取距离distance = distance + ext; }// LZ77滑动窗口计算获取量int[] arr = baos.GetInts();int d = arr.length - distance;if (d < 0) {d = 0;length = length + distance - arr.length;}// 读取滑动窗口,写入到结果for (int i=0; i<length; i++) {	int m = arr[ d + i];baos.Write(m);arr = baos.GetInts();}}else throw new java.lang.IllegalArgumentException(value+ "");}}else if (bType == 2) { // dynamic huffman 动态Huffman待实现throw new java.lang.UnsupportedOperationException(bType + "");}else throw new java.lang.IllegalArgumentException(bType + "");if (bFinal == 1) // 最后一个块break ;}// 结果int[] b = baos.GetInts();byte[] result = new byte[b.length];for (int i=0; i<b.length; i++) result[i] = (byte) b[i];return result;

测试结果如下:

将字符串"abcabcabcabcabcabcabcabcabcabcabcabc1111"写入到文件,

运行gzip程序(系统程序)压缩,

使用Java程序对gzip文件解析并显示解压后的内容。 (gzip使用了静态huffman)。

这篇关于GZIP文件格式解析和Inflate静态Huffman解压缩的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/955198

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图