📄 crc.cpp
字号:
// crc.cc// adapted slightly by Scott McPeak// originally was:/* crc32h.c -- package to compute 32-bit CRC one byte at a time using *//* the high-bit first (Big-Endian) bit ordering convention *//* *//* Synopsis: *//* gen_crc_table() -- generates a 256-word table containing all CRC *//* remainders for every possible 8-bit byte. It *//* must be executed (once) before any CRC updates. *//* *//* unsigned update_crc(crc_accum, data_blk_ptr, data_blk_size) *//* unsigned crc_accum; char *data_blk_ptr; int data_blk_size; *//* Returns the updated value of the CRC accumulator after *//* processing each byte in the addressed block of data. *//* *//* It is assumed that an unsigned long is at least 32 bits wide and *//* that the predefined type char occupies one 8-bit byte of storage. *//* *//* The generator polynomial used for this version of the package is *//* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 *//* as specified in the Autodin/Ethernet/ADCCP protocol standards. *//* Other degree 32 polynomials may be substituted by re-defining the *//* symbol POLYNOMIAL below. Lower degree polynomials must first be *//* multiplied by an appropriate power of x. The representation used *//* is that the coefficient of x^0 is stored in the LSB of the 32-bit *//* word and the coefficient of x^31 is stored in the most significant *//* bit. The CRC is to be appended to the data most significant byte *//* first. For those protocols in which bytes are transmitted MSB *//* first and in the same order as they are encountered in the block *//* this convention results in the CRC remainder being transmitted with *//* the coefficient of x^31 first and with that of x^0 last (just as *//* would be done by a hardware shift register mechanization). *//* *//* The table lookup technique was adapted from the algorithm described *//* by Avram Perez, Byte-wise CRC Calculations, IEEE Micro 3, 40 (1983).*/#define POLYNOMIAL 0x04c11db7Lstatic unsigned long crc_table[256];void gen_crc_table() /* generate the table of CRC remainders for all possible bytes */ { register int i, j; register unsigned long crc_accum; for ( i = 0; i < 256; i++ ) { crc_accum = ( (unsigned long) i << 24 ); for ( j = 0; j < 8; j++ ) { if ( crc_accum & 0x80000000L ) crc_accum = ( crc_accum << 1 ) ^ POLYNOMIAL; else crc_accum = ( crc_accum << 1 ); } crc_table[i] = crc_accum; } return; }unsigned long update_crc(unsigned long crc_accum, char const *data_blk_ptr, int data_blk_size) /* update the CRC on the data block one byte at a time */ { register int i, j; for ( j = 0; j < data_blk_size; j++ ) { i = ( (int) ( crc_accum >> 24) ^ *data_blk_ptr++ ) & 0xff; crc_accum = ( crc_accum << 8 ) ^ crc_table[i]; } return crc_accum; }// SM: block-level application// for thread safety, 'main' should crc something before making any threadsstatic int made_table = 0;unsigned long crc32(unsigned char const *data, int length){ if (!made_table) { made_table = 1; // sm: 9/18/00 11:19 gen_crc_table(); } unsigned long ret = update_crc(0xFFFFFFFF, (char*)data, length); ret = ret & 0xFFFFFFFF; // in case 'unsigned long' is 64 bits return ret;}// ----------------- test code ------------------------------#ifdef TEST_CRC#include <stdio.h>void testCrc(char const *data, int length, unsigned long crc){ printf("computed crc is 0x%08lX, expected is 0x%08lX\n", crc32((unsigned char*)data, length), ~crc);}int main(){ /* 40 Octets filled with "0" */ /* CPCS-UU = 0, CPI = 0, Length = 40, CRC-32 = 864d7f99 */ char pkt_data1[48]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x28,0x86,0x4d,0x7f,0x99}; /* 40 Octets filled with "1" */ /* CPCS-UU = 0, CPI = 0, Length = 40, CRC-32 = c55e457a */ char pkt_data2[48]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,0x00,0x00,0x28,0xc5,0x5e,0x45,0x7a}; /* 40 Octets counting: 1 to 40 */ /* CPCS-UU = 0, CPI = 0, Length = 40, CRC-32 = bf671ed0 */ char pkt_data3[48]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a, 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e, 0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x00,0x00,0x00,0x28,0xbf,0x67,0x1e,0xd0}; /* 40 Octets counting: 1 to 40 */ /* CPCS-UU = 11, CPI = 22, CRC-32 = acba602a */ char pkt_data4[48]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a, 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e, 0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x11,0x22,0x00,0x28,0xac,0xba,0x60,0x2a}; testCrc(pkt_data1, 44, 0x864d7f99); testCrc(pkt_data2, 44, 0xc55e457a); testCrc(pkt_data3, 44, 0xbf671ed0); testCrc(pkt_data4, 44, 0xacba602a); return 0;}#endif // TEST_CRC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -