#include #include #include #define BYTE_WIDTH 8 #define REMAINDER_WIDTH 8 #define MESSAGE_LENGTH 3 #define LOOKUP_TABLE_DATA "CRC-8.dat" #define TWO_UP_EIGHT 256 // Define a boolean type as an enumeration. typedef enum { FALSE = 0, TRUE = 1 } Bool; const unsigned char PowersOfTwo[REMAINDER_WIDTH] = {1, 2, 4, 8, 16, 32, 64, 128}; // This truncated "Divisor", when displayed in binary, looks like this (11010101). const unsigned char Poly = 213; // This function performs a Byte-wise "LookupTable" CRC calculation on "NumberOfBytes" Bytes, starting at "DataMessage". // The divisor used is defined in the constant "Poly". // The value returned by the function is the "CRC-Digest". unsigned char LookupTableCrc(const unsigned char *DataMessage, unsigned int NumberOfBytes, const unsigned char *LookupTable){ int X; // Because looking up "0" in the table returns "0", it is safe to use a table lookup to fill the "WorkingRegister" with its initial "DataMessage" value. register unsigned char WorkingRegister = 0; // Query the "LookupTable" exactly "NumberOfBytes" times. Perform lookups using the value inside of "WorkingRegister" as the index. // After each table query, "XOR" the value returned by "LookupTable" with the next most significant Byte in "DataMessage". // "X" is the location of the next data Byte to pull into the calculation. for ( X = 0; X < NumberOfBytes; X++ ) WorkingRegister = LookupTable[WorkingRegister] ^ DataMessage[X]; return WorkingRegister; } // Simply print out "ThisByte" using "1"s and "0"s. void PrintByteInBinary(unsigned char ThisByte){ unsigned int X; char HoldOut[BYTE_WIDTH + 1]; for ( X = 0; X < BYTE_WIDTH; X++ ) HoldOut[X] = (ThisByte & PowersOfTwo[BYTE_WIDTH - 1 - X])? '1': '0'; HoldOut[BYTE_WIDTH] = '\0'; printf("%s", HoldOut); } int main(){ unsigned int X; // Include an extra Byte in the message to test the trailing-zeros CRC property. unsigned char DemonstrationMessage[MESSAGE_LENGTH + 1] = {202, 45, 166, 0}; unsigned char TheDigest; unsigned char *TheLookupTable = (unsigned char*)malloc(TWO_UP_EIGHT*sizeof(unsigned char)); FILE *TableFile; // Read the precompiled lookup-table from "CRC-8.dat" directly into "TheLookupTable". TableFile = fopen(LOOKUP_TABLE_DATA, "rb"); fread(TheLookupTable, sizeof(unsigned char), TWO_UP_EIGHT, TableFile); fclose(TableFile); printf("\n---------------------------------------------------------------------------------\n"); printf("\nBehold the |%d| Byte DataMessage - |", MESSAGE_LENGTH); for ( X = 0; X < MESSAGE_LENGTH; X++ ) { PrintByteInBinary(DemonstrationMessage[X]); printf("|"); } printf("\n\n"); TheDigest = LookupTableCrc(DemonstrationMessage, MESSAGE_LENGTH*sizeof(unsigned char), TheLookupTable); printf("Behold TheDigest-|%d|-|", TheDigest); PrintByteInBinary(TheDigest); printf("|\n"); printf("\n---------------------------------------------------------------------------------\n"); // Calculate "TheDigest" with appended zeros, and then replace the trailing zeros with this number. // Recalculate "TheDigest", and this time the digest should compute to zero. printf("\nAppend \"W\" zeros to the DataMessage - |"); for ( X = 0; X < (MESSAGE_LENGTH + 1); X++ ) { PrintByteInBinary(DemonstrationMessage[X]); printf("|"); } printf("\n\n"); TheDigest = LookupTableCrc(DemonstrationMessage, MESSAGE_LENGTH*sizeof(unsigned char) + 1, TheLookupTable); printf("Behold TheDigest-|%d|-|", TheDigest); PrintByteInBinary(TheDigest); printf("|\n"); printf("\n---------------------------------------------------------------------------------\n"); DemonstrationMessage[MESSAGE_LENGTH] = TheDigest; printf("\n\"TheDigest\" of this DataMessage should be zero - |"); for ( X = 0; X < (MESSAGE_LENGTH + 1); X++ ) { PrintByteInBinary(DemonstrationMessage[X]); printf("|"); } printf("\n\n"); TheDigest = LookupTableCrc(DemonstrationMessage, MESSAGE_LENGTH*sizeof(unsigned char) + 1, TheLookupTable); printf("Behold TheDigest-|%d|-|", TheDigest); PrintByteInBinary(TheDigest); printf("|\n"); printf("\n---------------------------------------------------------------------------------\n"); printf("\n"); return 0; }