ZIP加密所用CRC-32与zlib的crc32实现不一致的原因是什么?
差异原因说明
你的实现没有错误,二者不匹配是因为zlib的CRC32实现和ZIP传统加密算法要求的CRC32变体存在两处设计差异,你的转换函数刚好适配了这两处差异:
1. 输入处理逻辑不同
zlib实现的是标准IEEE 802.3 CRC32算法,内部会自动对每个输入字节先做按位取反再参与计算;而ZIP传统加密流程中使用的CRC32变体要求直接使用原始输入字节计算。
你代码中~ch & 0xFF的操作,就是先对输入字节取反后再传入zlib的crc32接口,刚好抵消了zlib内部自动做的输入取反步骤,得到符合ZIP规范要求的输入处理结果。
2. 输出处理逻辑不同
标准CRC32完成全流程计算后,会对整个32位计算结果统一按位取反再返回;而ZIP加密用的CRC32仅要求对结果的最高8位取反,低24位保持原始计算结果不变。
你代码中(~crc & 0xFF000000) + (crc & 0x00FFFFFF)的操作,就是仅将zlib返回结果的最高8位取反,保留低24位不变,刚好匹配ZIP加密的输出要求。
直接使用zlib原生接口报错的原因
如果直接替换为zlib原生crc32调用,相当于额外多执行了「输入字节重复取反」「低24位结果错误取反」两步操作,最终得到的CRC值完全不符合ZIP加密的密钥更新逻辑,生成的解密密钥错误,在校验12字节加密头部时匹配不到文件修改时间的高8位,就会抛出密码错误的异常。
内容的提问来源于stack exchange,提问作者Michal Charemza
相关产品推荐
相关产品推荐

