I'm having difficulty finding the right CRC32 algorithms which are used
by the various ZIP programs to calculate a CRC that they will each agree
is correct. There are two aspects of this difficulty: one is that there
are several algorithms which claim to be used by PKZIP, the second is
that one of those I've tried might be right but that I've coded it
incorrectly, and the third (huh?) is that there are two routines which
must be correctly coded to get the correct result.
If any of you wish the challenge please search for the algorithms on the
Internet and try it in the test script below.
It seems to me that the most promising algorithms are those in the files
"crc32.c" and "crc32.h" from:
64-bit <
ftp://ftp.info-zip.org/pub/infozip/win32/zip300xn-x64.zip>
32-bit <
ftp://ftp.info-zip.org/pub/infozip/win32/zip300xn.zip>
Those are the two I have below (in :setTable and :getCRC32) and they
obviously fail, which might be because of my coding.
The test script writes a short file and uses CERTUTIL to get a hex dump,
which is used to calculate the value of each byte. I have stored this
file (not the hex dump) with ZIP and UNZIP reports a CRC of 0xa8a9215b,
which is -1465310885. So the goal is to get this script to calculate
"-1465310885" from the test file.
Thank you,
Frank
:: BEGIN SCRIPT :::::::::::::::::::::::::::::::::::::::::::::::::::::
:: REQUIRES CERTUTIL.exe
@Echo OFF
SetLocal EnableExtensions EnableDelayedExpansion
Set "fileText=%TEMP%\crc32.txt"
Set "fileHex=%TEMP%\crc32.hex"
Echo;How now brown cow? >"%fileText%"
:: When the above file is calculated by unzip the CRC is
:: 0xa8a9215b, which is -1465310885.
:: Create a hex dump of the file so that each byte value can
:: be calculated from the hex-pair:
CertUtil -f -encodeHex "%fileText%" "%fileHex%" 4 >NUL: 2>&1
:: You can speed up the testing by calling ':setTable' once without
:: SETLOCAL to get it in your console's environment, then REM this line.
Call :setTable
:: Calculate the CRC:
Call :getCRC32 crc "%fileHex%"
:: Examine the result:
Echo; Expected crc32=-1465310885
Echo;Calculated crc32=%crc%
ERASE "%fileText%" "%fileHex%"
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:setTable
:: /* generate a crc for every 8-bit value */
:: for (n = 0; n < 256; n++) {
:: c = (ulg)n;
:: for (k = 8; k; k--)
:: c = c & 1 ? xor ^ (c >> 1) : c >> 1;
:: crctab_p[n] = REV_BE(c);
:: }
Set /A "xor=0xEDB88320"
For /L %%n in (0, 1, 255) Do (
Set /A "c=%%n"
For /L %%k in (8, -1, 1) Do (
Set /A "t=c&1, c>>=1"
If !t! NEQ 0 Set /A "c=xor^c"
Set /A "TABLE%%n=c"
)
)
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:getCRC32 <var name> <name of hex file>
::# define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
Set "crc=0xFFFFFFFF"
For /F "usebackq delims=" %%L in ("%~2") Do (
For %%B in (%%L) Do (
Set /A "n=(crc^0x%%B)&0xFF"
For %%i in (!n!) Do Set "n=!TABLE%%i!"
Set /A "crc=n^(crc>>8)"
)
)
Set /A "crc^=0xFFFFFFFF"
EndLocal & Set "%~1=%crc%"
Goto :EOF
:: END SCRIPT ::::::::::::::::::::::::::::::::::::::::::::::::::::