#include #include /** * The polynomial used is the standard one, which is * x ^ 16 + x ^ 12 + x ^ 5 + x ^ 0 * With each nonzero term represented by a 1 and each * missing term represented by a 0, the binary representation is: * * 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 * 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 * * If we let the top bit (representing x^16) be an implied bit, * the result is 0000 1000 0001 0001. To make the implementation * simple, we reverse this to get 1000 0100 0000 1000 = 0x8408. */ #define RPOLY 0x8408 /*************************************************************************** * function prototype ***************************************************************************/ unsigned short c12crc(const unsigned char *buffer, unsigned short len); /*************************************************************************** * test vector definitions ***************************************************************************/ typedef struct { const unsigned short expected; /* the CRC expected for this vector */ const unsigned short length; /* the length, in bytes of this vector */ const unsigned char *s; /* the vector data */ } testVectorStruct; const testVectorStruct v[] = { { 0x1310, 7, (const unsigned char *)"\xEE\x00\x00\x00\x00\x01\x20"}, { 0x8270, 7, (const unsigned char *)"\xEE\x00\x20\x00\x00\x01\x20"}, { 0x2a5e, 8, (const unsigned char *)"\xFE\xDC\xBA\x98\x76\x54\x32\x10"}, { 0x470f, 2, (const unsigned char *)"\x00\x00"}, }; /**************************************************************************** * * Calculates the C12.22 CRC * * Does the C12 style CRC, which consumes bytes from low memory to high * memory, calculating a CRC from the passed starting value by processing * each byte least significant bit first. * * This code is designed to be used on a little-endian machine. * ****************************************************************************/ unsigned short c12crc(const unsigned char *buffer, unsigned short len) { unsigned char i; unsigned int olddata; unsigned short crc = 0xffff; for (; len; buffer++, len--) { crc ^= (unsigned int)0xff & *buffer; for (i=0; i < 8; i++) { olddata = crc & 0x0001; crc >>= 1; if (olddata) crc ^= RPOLY; } } crc = ~crc; olddata = crc; crc = (crc << 8) | ((olddata >> 8) & 0xff); return crc; } /**************************************************************************** * Main code serves as a test driver. ****************************************************************************/ int main() { int i, calculated; for (i = 0; i < sizeof(v)/sizeof(v[0]); i++) { calculated = c12crc(v[i].s, v[i].length); printf("calculated crc[%d] = 0x%4.4x (expected 0x%4.4x)\n", i, calculated, v[i].expected); assert(calculated == v[i].expected); } return 0; }