循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。
本文实现 CRC16 的C语言校验算法,采用的是查表的方法。CRC多项式是 x16+x15+x2+1(0x8005),CRC的初始值为0xFFFF,是modbus的CRC校验算法。
1 crc.c
#include "crc16.h"
/* CRC16 余式表 */
static uint16_t crctalbeabs[] = {
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
};
/*!
* 功 能: CRC16校验
* param1: 指向要校验的数据的指针
* param2: 要校验的数据的长度
* retval: 校验所得到的值,uint16_t 类型
*
* 说 明: 本次CRC校验为查表法,多项式为 x16+x15+x2+1(0x8005),CRC的初始值为0xFFFF
*/
uint16_t Crc16(uint8_t *ptr, uint32_t len)
{
uint16_t crc = 0xffff;
uint32_t i;
uint8_t ch;
for (i = 0; i < len; i++) {
ch = *ptr++;
crc = crctalbeabs[(ch ^ crc) & 15] ^ (crc >> 4);
crc = crctalbeabs[((ch >> 4) ^ crc) & 15] ^ (crc >> 4);
}
return crc;
}
2 crc.h
#ifndef _CRC_H_
#define _CRC_H_
#include <stdint.h>
uint16_t Crc16(uint8_t *ptr, uint32_t len);
#define HIG_UINT16(a) ( ((a)>>8) & 0xFF )
#define LOW_UINT16(a) ( (a) & 0xFF )
#define HIG_UINT8(a) ( ((a)>>4) & 0x0F )
#define LOW_UINT8(a) ( (a) & 0x0F )
#endif /* crc.h */