初级会员

- 积分
- 58
- 金钱
- 58
- 注册时间
- 2014-7-13
- 在线时间
- 0 小时
|
关于CRC校验的网上资料比较杂乱,而其本身又有较深的数学背景,导致大家通常难以理解其算法。下面分享一段我自己的软件代码,与STM32的CRC计算单元相互印证,希望能够帮助大家理解CRC校验。代码参照IEEE 802.3协议编写,软件实现CRC-32快速校验算法:
(纯属个人研究,如有疏漏之处,还望多多包涵)
/*
Name: Main.c
Copyright: Free
Author: Lulai Zhu
Date:
Description:
Calculation of CRC-32
*/
#include <stdio.h>
#include <stdlib.h>
#define POLYNOMIAL 0x04C11DB7 //CRC-32简记式
typedef unsigned char BYTE;
typedef unsigned long ULONG;
ULONG g_aulTable[256]; //8位数据余式表
void InitTable(void); //初始化余式表
ULONG CalCrc(const BYTE *pbyData, int iLen); //计算CRC余式
int main(void)
{
BYTE abyData[4] = {0x12, 0x34, 0x56, 0x78};
ULONG ulCrc = 0x0;
InitTable();
ulCrc = CalCrc(abyData, 4);
printf("ulCrc = 0x%08X\n", ulCrc);
system("pause");
exit(EXIT_SUCCESS);
}
void InitTable(void)
{
ULONG ulReg = 0x0; //移位寄存器,初始化为0x0
int i = 0;
int j = 0;
for (i = 0; i < 256; i++) //总共256个余式
{
ulReg = ((ULONG)i << 24); //8位数据左移24位,然后记入寄存器
for (j = 0; j < 8; j++) //总共8位数据
{
if ((ulReg >> 31) == 0x1) //如果寄存器最高位为1
{
ulReg = (ulReg << 1) ^ POLYNOMIAL; //寄存器左移1位,并与简记式异或
}
else
{
ulReg <<= 1; //寄存器左移1位
}
}
g_aulTable = ulReg; //将结果记入余式表
}
return;
}
ULONG CalCrc(const BYTE *pbyData, int iLen)
{
ULONG ulReg = 0xFFFFFFFF; //移位寄存器,初始化为0xFFFFFFFF
int i = 0;
/* 通过8位数据余式表,快速计算CRC余式,具体解释请参考:
http://blog.csdn.net/zhaodm/article/details/3711034 */
for (i = 0; i < iLen; i++)
{
ulReg = (ulReg << 8) ^ g_aulTable[(ulReg >> 24) ^ pbyData];
}
return ulReg;
}
|
|