如何验证 Zip 文件的 CRC-32 计算

E23*_*235 1 zip crc32 checksum crc

我想验证我的 ZIP 文件是否具有正确的 CRC-32 校验和。
\n我读到,在 ZIP 文件中,CRC-32 数据位于字节 14 到 17 中:

\n
Offset  Bytes   Description[30]\n0        4  Local file header signature = 0x04034b50 (read as a little-endian number)\n4        2  Version needed to extract (minimum)\n6        2  General purpose bit flag\n8        2  Compression method\n10       2  File last modification time\n12       2  File last modification date\n14       4  CRC-32 of uncompressed data\n18       4  Compressed size\n22       4  Uncompressed size\n26       2  File name length (n)\n28       2  Extra field length (m)\n30       n  File name\n30+n     m  Extra field  \n
Run Code Online (Sandbox Code Playgroud)\n

我想验证我创建的简单 ZIP 文件的 CRC-32 校验和:

\n
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n-----------------------------------------------\n50 4B 03 04 14 00 00 00 00 00 38 81 1C 51 4C 18  | PK........8..QL.\nC7 8C 02 00 00 00 02 00 00 00 07 00 00 00 31 32  | \xc3\x87\xc5\x92............12\n33 2E 64 61 74 73 73 50 4B 01 02 14 00 14 00 00  | 3.datssPK.......\n00 00 00 38 81 1C 51 4C 18 C7 8C 02 00 00 00 02  | ...8..QL.\xc3\x87\xc5\x92.....\n00 00 00 07 00 00 00 00 00 00 00 01 00 20 00 00  | ............. ..\n00 00 00 00 00 31 32 33 2E 64 61 74 50 4B 05 06  | .....123.datPK..\n00 00 00 00 01 00 01 00 35 00 00 00 27 00 00 00  | ........5...\'...\n00 00                                            | ..\n
Run Code Online (Sandbox Code Playgroud)\n

CRC-32 是: 0x4C18C78C
\n我去了这个CRC-32 在线计算器,并从文件中添加了以下未压缩的行:

\n
50 4B 03 04 14 00 00 00 00 00 38 81 1C 51\n
Run Code Online (Sandbox Code Playgroud)\n

这是结果:

\n
Algorithm           Result      Check       Poly            Init        RefIn   RefOut  XorOut     \nCRC-32              0x6A858174  0xCBF43926  0x04C11DB7  0xFFFFFFFF      true    true    0xFFFFFFFF\nCRC-32/BZIP2        0xE3FA1205  0xFC891918  0x04C11DB7  0xFFFFFFFF      false   false   0xFFFFFFFF\nCRC-32C             0xB578110E  0xE3069283  0x1EDC6F41  0xFFFFFFFF      true    true    0xFFFFFFFF\nCRC-32D             0xAFE2EEA4  0x87315576  0xA833982B  0xFFFFFFFF      true    true    0xFFFFFFFF\nCRC-32/MPEG-2       0x1C05EDFA  0x0376E6E7  0x04C11DB7  0xFFFFFFFF      false   false   0x00000000\nCRC-32/POSIX        0xFF9B3071  0x765E7680  0x04C11DB7  0x00000000      false   false   0xFFFFFFFF\nCRC-32Q             0x79334F11  0x3010BF7F  0x814141AB  0x00000000      false   false   0x00000000\nCRC-32/JAMCRC       0x957A7E8B  0x340BC6D9  0x04C11DB7  0xFFFFFFFF      true    true    0x00000000\nCRC-32/XFER         0xA7F36A3F  0xBD0BE338  0x000000AF  0x00000000      false   false   0x00000000  \n
Run Code Online (Sandbox Code Playgroud)\n

但它们都不等于:0x4C18C78C

\n

我究竟做错了什么?ZIP的CRC-32是之前所有字节(0-13)的计算,不是吗?

\n

pmq*_*mqs 5

您针对在线 CRC 计算器运行的字节序列不是未压缩的字节。

50 4B 03 04 14 00 00 00 00 00 38 81 1C 51
Run Code Online (Sandbox Code Playgroud)

这些字节是 zip 文件的前几个字节。zip 中的 CRC32 值是通过针对完整的未压缩负载运行 CRC32 算法来计算的。在您的情况下,有效负载是两个字节序列“ss”。

为了解决这个问题,我将您的十六进制转储转换回 zip 文件,tmp.zip. 它包含一个成员123.dat

$ unzip -lv tmp.zip 
Archive:  tmp.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       2  Stored        2   0% 2020-08-28 16:09 8cc7184c  123.dat
--------          -------  ---                            -------
       2                2   0%                            1 file
Run Code Online (Sandbox Code Playgroud)

当我将该成员提取到 stdout 和管道时hexdump,我们发现它包含两个字节字符串“ss”(十六进制 73 73)

$ unzip -p tmp.zip | hexdump -C
00000000  73 73                                             |ss|
    
Run Code Online (Sandbox Code Playgroud)

最后,正如另一条评论中已经提到的,您可以通过运行来检查 CRC 值是否正确unzip -t

$ unzip -t tmp.zip 
Archive:  tmp.zip
    testing: 123.dat                  OK
No errors detected in compressed data of tmp.zip.
Run Code Online (Sandbox Code Playgroud)