// CRC32 (EDB88320 poly) adapted to use nybble lookup table (only 16 entries!)
// assumes your long is 32-bits
//
// Idea from Stewart's article on China CRC code in "Operation Aurora"
//
// andrewl
// Feb09_2010
#include
// these are the CRC32's of all nybbles
//
unsigned long residues[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
// yes, this is longer than it has to be, but verbosity was a goal
//
unsigned long calculate_crc(unsigned char *stream, int n)
{
unsigned char next_nybbles;
unsigned long residue;
unsigned long dividend_new;
// no mathematical significance here, just crc-32 convention
residue = 0xFFFFFFFF;
// the real work!
for(int i=0; i> 4); // add to current residue (less the already-indexed top 4 terms)
next_nybbles >>= 4;
dividend_new = residue ^ next_nybbles; // again, for next bits
residue = residues[dividend_new & 0xF] ^
(residue >> 4);
}
// no mathematical significance here, just crc-32 convention
return residue ^ 0xFFFFFFFF;
}
int main(int argc, char *argv[])
{
// need some better test vectors here
unsigned char rawData[60] = {
0x54, 0x68, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x20,
0x66, 0x61, 0x72, 0x6D, 0x65, 0x72, 0x20, 0x77, 0x68, 0x6F, 0x20, 0x68,
0x61, 0x64, 0x20, 0x61, 0x20, 0x64, 0x6F, 0x67, 0x20, 0x61, 0x6E, 0x64,
0x20, 0x42, 0x69, 0x6E, 0x67, 0x6F, 0x20, 0x77, 0x61, 0x73, 0x20, 0x68,
0x69, 0x73, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x2C, 0x20, 0x6F, 0x68, 0x2C
};
printf("%08X (should be 329D549F)\n", calculate_crc(rawData, sizeof(rawData)));
}