#include "crc.h" /****************************Info********************************************** * Name: InvertUint8 * Note: 把字节颠倒过来,如0x12变成0x48 0x12: 0001 0010 0x48: 0100 1000 *****************************************************************************/ void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf) { int i; unsigned char tmp[4]={0}; for(i=0;i< 8;i++) { if(srcBuf[0]& (1 << i)) tmp[0]|=1<<(7-i); } dBuf[0] = tmp[0]; } void InvertUint16(unsigned short *dBuf,unsigned short *srcBuf) { int i; unsigned short tmp[4]={0}; for(i=0;i< 16;i++) { if(srcBuf[0]& (1 << i)) tmp[0]|=1<<(15 - i); } dBuf[0] = tmp[0]; } void InvertUint32(unsigned int *dBuf,unsigned int *srcBuf) { int i; unsigned int tmp[4]={0}; for(i=0;i< 32;i++) { if(srcBuf[0]& (1 << i)) tmp[0]|=1<<(31 - i); } dBuf[0] = tmp[0]; } /****************************Info********************************************** * Name: CRC-16/CCITT x16+x12+x5+1 * Width: 16 * Poly: 0x1021 * Init: 0x0000 * Refin: True * Refout: True * Xorout: 0x0000 * Alias: CRC-CCITT,CRC-16/CCITT-TRUE,CRC-16/KERMIT *****************************************************************************/ #if 0 unsigned short CRC16_CCITT(unsigned char *data, unsigned int datalen) { unsigned short wCRCin = 0x0000; unsigned short wCPoly = 0x1021; unsigned char wChar = 0; while (datalen--) { wChar = *(data++); InvertUint8(&wChar,&wChar); wCRCin ^= (wChar << 8); for(int i = 0;i < 8;i++) { if(wCRCin & 0x8000) wCRCin = (wCRCin << 1) ^ wCPoly; else wCRCin = wCRCin << 1; } } InvertUint16(&wCRCin,&wCRCin); return (wCRCin); } #else //这里为了效率,我们不需要将所有Refin和refout为true的输入输出数据移位转换 //只需要将poly二项式转换后,运算时将左移变为右移 unsigned short CRC16_CCITT(unsigned char *data, unsigned int datalen) { unsigned short wCRCin = 0x0000; unsigned short wCPoly = 0x1021; unsigned char wChar = 0; InvertUint16(&wCPoly,&wCPoly); while (datalen--) { wCRCin ^= *(data++); for(int i = 0;i < 8;i++) { if(wCRCin & 0x01) wCRCin = (wCRCin >> 1) ^ wCPoly; else wCRCin = wCRCin >> 1; } } return (wCRCin); } #endif