CRC16_C语言实现
计算实现CRC16,
可以通过配置,初值、多项式、输出入是否反转、输出是否反转、结果异或值来选定不同的模式。
/* ************************************************************************************************************** * 函数名称: InvertUint8 * 函数功能: 将uint8类型的数字进行bit全部反转 * 函数入口: dBuf [out] 待反转的值 srcBuf [in] 反转后的值 * 函数返回: 计算CRC的结果 ***************************************************************************************************************/ static void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf) { int i; unsigned char tmp[4]; tmp[0] = 0; for(i=0;i< 8;i++) { if(srcBuf[0]& (1 << i)) tmp[0]|=1<<(7-i); } dBuf[0] = tmp[0]; } /* ************************************************************************************************************** * 函数名称: InvertUint16 * 函数功能: 将uint16类型的数字进行bit全部反转 * 函数入口: dBuf [out] 待反转的值 srcBuf [in] 反转后的值 * 函数返回: 计算CRC的结果 ***************************************************************************************************************/ static void InvertUint16(unsigned short *dBuf,unsigned short *srcBuf) { int i; unsigned short tmp[4]; tmp[0] = 0; for(i=0;i< 16;i++) { if(srcBuf[0]& (1 << i)) tmp[0]|=1<<(15 - i); } dBuf[0] = tmp[0]; } /* ************************************************************************************************************** * 函数名称: CRC16 * 函数功能: 计算CRC16 * 函数入口: puchMsg [in] 待计算的数据 usDataLen [in] 待计算数据的长度 * 函数返回: 计算CRC的结果 ***************************************************************************************************************/ unsigned short CRC16(unsigned char *puchMsg, unsigned int usDataLen) { unsigned short wCRCin = 0xFFFF; //初始值,根据模式进行设置 unsigned short wCPoly = 0x1021; //多项式,根据模式进行设置 unsigned char wChar = 0; while (usDataLen--) { wChar = *(puchMsg++); 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); //输出数据反转,根据模式进行选择是否启用 wCRCin &= 0xFFFF; wCRCin ^= 0xFFFF; //输出异或,根据模式设置异或的数值 return (wCRCin) ; }
#include <stdio.h> /* ************************************************************************************************************** * 函数名称: InvertUint8 * 函数功能: 将uint8类型的数字进行bit全部反转 * 函数入口: dBuf [out] 待反转的值 srcBuf [in] 反转后的值 * 函数返回: 计算CRC的结果 ***************************************************************************************************************/ static void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf) { int i; unsigned char tmp[4]; tmp[0] = 0; for(i=0;i< 8;i++) { if(srcBuf[0]& (1 << i)) tmp[0]|=1<<(7-i); } dBuf[0] = tmp[0]; } /* ************************************************************************************************************** * 函数名称: InvertUint16 * 函数功能: 将uint16类型的数字进行bit全部反转 * 函数入口: dBuf [out] 待反转的值 srcBuf [in] 反转后的值 * 函数返回: 计算CRC的结果 ***************************************************************************************************************/ static void InvertUint16(unsigned short *dBuf,unsigned short *srcBuf) { int i; unsigned short tmp[4]; tmp[0] = 0; for(i=0;i< 16;i++) { if(srcBuf[0]& (1 << i)) tmp[0]|=1<<(15 - i); } dBuf[0] = tmp[0]; } /* ************************************************************************************************************** * 函数名称: CRC16 * 函数功能: 计算CRC16 * 函数入口: puchMsg [in] 待计算的数据 usDataLen [in] 待计算数据的长度 * 函数返回: 计算CRC的结果 ***************************************************************************************************************/ unsigned short CRC16(unsigned char *puchMsg, unsigned int usDataLen) { unsigned short wCRCin = 0xFFFF; //初始值,根据模式进行设置 unsigned short wCPoly = 0x1021; //多项式,根据模式进行设置 unsigned char wChar = 0; while (usDataLen--) { wChar = *(puchMsg++); 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); //输出数据反转,根据模式进行选择是否启用 wCRCin &= 0xFFFF; wCRCin ^= 0xFFFF; //输出异或,根据模式设置异或的数值 return (wCRCin) ; } int main(int argc,char *argv[]) { unsigned char in_data[4]={0x31,0x32,0x33,0x34}; unsigned int in_len = 4; unsigned short out_data; out_data = CRC16(in_data,in_len); printf("CRC16 %02X \r\n",out_data); return 0; }