// CRC-32
#define CRCPOLY 0xEDB88320
#define CRCINIT 0xFFFFFFFF
UINT g_crc_precalc[4][256];
void CRC32Init() {
for(UINT i = 0; i <= 0xFF; i++) {
UINT x = i;
for(UINT j = 0; j < 8; j++)
x = (x>>1) ^ (CRCPOLY & (-(INT)(x & 1)));
g_crc_precalc[0][i] = x;
}
for(UINT i = 0; i <= 0xFF; i++) {
UINT c = g_crc_precalc[0][i];
for(UINT j = 1; j < 4; j++) {
c = g_crc_precalc[0][c & 0xFF] ^ (c >> 8);
g_crc_precalc[j][i] = c;
}
}
}
UINT CRC32(const CHAR* key, SIZE_T len) {
UINT crc = CRCINIT;
SIZE_T ndwords = len / sizeof(DWORD);
for(; ndwords; ndwords--) {
crc ^= *(DWORD*)key;
crc =
g_crc_precalc[3][(crc ) & 0xFF] ^
g_crc_precalc[2][(crc >> 8) & 0xFF] ^
g_crc_precalc[1][(crc >> 16) & 0xFF] ^
g_crc_precalc[0][(crc >> 24) & 0xFF];
key += sizeof(DWORD);
}
if (len & sizeof(WORD)) {
UINT c = crc ^ *(WORD*)key;
crc = g_crc_precalc[1][(c ) & 0xFF] ^
g_crc_precalc[0][(c >> 8) & 0xFF] ^ (crc >> 16);
key += sizeof(WORD);
}
if (len & sizeof(BYTE))
crc = g_crc_precalc[0][(crc ^ *key) & 0xFF] ^ (crc >> 8);
return ~crc;
}