如何解析通用位标志第3位已置位的ZIP文件?
解析带数据描述符的流式ZIP文件方案
针对你遇到的通用位标志第3位置位、本地文件头压缩大小为0的ZIP文件,核心解决思路是结合ZIP规范的结构特性,分场景处理:
1. 先定位中央目录(EOCD)获取真实文件大小
这是最可靠的方法,因为流式ZIP最终生成时,中央目录会补充完整的文件元数据(包括真实的压缩大小、未压缩大小、CRC32):
- 先找End of Central Directory (EOCD) 记录:它的签名是
0x06054b50,位于文件末尾区域(最多可能跟随64KB的注释,可从文件末尾往前扫描)。 - 从EOCD中读取中央目录的起始偏移量和条目总数,遍历每个中央目录条目:每个条目包含对应本地文件头的偏移地址、文件名、真实的压缩大小/未压缩大小/CRC32。
- 对于标记了第3位通用位的文件,用中央目录里的真实压缩大小,从本地文件头结束的位置(即
30 + 文件名长度 + 额外字段长度字节后)截取对应长度的数据,这就是完整的压缩/未压缩数据,紧随其后的就是数据描述符。
2. 针对不同压缩方法的直接处理(适用于无法先访问EOCD的场景)
如果必须流式处理(无法先定位EOCD),则按压缩方法分别处理:
- 压缩方法8(Deflate):利用Deflate的块结构,每个块的开头有3位标志,其中最后一位表示是否为最后一块。解析Deflate数据直到遇到最后一块,即可确定压缩数据的结束位置,之后就是数据描述符。
- 压缩方法0(无压缩):此时只能扫描数据区域寻找数据描述符签名
0x08074b50,但要注意数据中可能存在伪签名。可以通过以下方式验证:- 找到候选签名后,读取后续的4字节CRC32、4字节压缩大小、4字节未压缩大小,检查这些值是否符合逻辑(比如大小非负,若本地文件头有临时CRC也可对比);
- 若验证通过,即可确定这是真实的数据描述符,后续就是下一个本地文件头或中央目录。
3. 数据描述符的规范验证
数据描述符的标准结构是:0x08074b50(签名) + CRC32(4字节) + 压缩大小(4字节) + 未压缩大小(4字节)
当通用位第3位置位时,规范要求数据描述符必须包含签名(避免与文件数据混淆),所以只要严格匹配签名+后续字段的合理性,就能准确定位。
内容的提问来源于stack exchange,提问作者cdauth
相关产品推荐
相关产品推荐

