一 概念:
循环冗余码校验英文名称为Cyclical Redundancy Check,简称CRC。它是利用除法及余数的原理来作错误侦测(Error Detecting)的。实际应用时,发送装置计算出CRC值并随数据一同发送给接收装置,接收装置对收到的数据重新计算CRC并与收到的CRC相比较,若两个CRC值不同,则说明数据通讯出现错误。
二 CRC16源码解析:
1 函数实现
代码语言:javascript复制#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#define CRC_POLY_16 0xA001
#define CRC_START_16 0x0000
static bool crc_tab16_init = false;
static uint16_t crc_tab16[256];
/*
* uint16_t crc_16( const unsigned char *input_str, size_t num_bytes );
*
* The function crc_16() calculates the 16 bits CRC16 in one pass for a byte
* string of which the beginning has been passed to the function. The number of
* bytes to check is also a parameter. The number of the bytes in the string is
* limited by the constant SIZE_MAX.
*/
uint16_t crc_16( const unsigned char *input_str, size_t num_bytes )
{
uint16_t crc;
const unsigned char *ptr;
size_t a;
if ( ! crc_tab16_init ) init_crc16_tab();
crc = CRC_START_16;
ptr = input_str;
if ( ptr != NULL ) for (a=0; a<num_bytes; a ) {
crc = (crc >> 8) ^ crc_tab16[ (crc ^ (uint16_t) *ptr ) & 0x00FF ];
}
return crc;
} /* crc_16 */
/*
* static void init_crc16_tab( void );
*
* For optimal performance uses the CRC16 routine a lookup table with values
* that can be used directly in the XOR arithmetic in the algorithm. This
* lookup table is calculated by the init_crc16_tab() routine, the first time
* the CRC function is called.
*/
void init_crc16_tab( void )
{
uint16_t i;
uint16_t j;
uint16_t crc;
uint16_t c;
for (i=0; i<256; i ) {
crc = 0;
c = i;
for (j=0; j<8; j ) {
if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ CRC_POLY_16;
else crc = crc >> 1;
c = c >> 1;
}
crc_tab16[i] = crc;
}
crc_tab16_init = true;
} /* init_crc16_tab */
2 计算结果:
代码语言:javascript复制#include <stdio.h>
#include <string.h>
typedef unsigned char uint8_t;
uint8_t test_data[20];
int main()
{
uint16_t crc_value = 0x00;
memset(test_data,0x11,20);
crc_value = crc_16(test_data,10);
printf("crc_value is:0x%x nr",crc_value);
return 0;
}