#include <string.h>
#include "stdlib.h"
unsigned int char2int(char *str)
{
unsigned int count=0, ret=0
for(count = 0count<strlen(str)count++)
{
ret = ret<<1
if('0' != str[count])
{ ret+=1}
}
return ret
}
unsigned int getR(char *str)
{
unsigned int c =0
int ret = strlen(str)-1
for(c=0c <strlen(str)c++)
{if(str[c] != '0')<br/> {return ret-c}
}
}
int getRi(unsigned int num)
{
int c =0
for(num != 0c++)
{num = num>>1}
return c
}
void CRC(char *scode, char *p, char*g )
{
unsigned int iP = char2int(p)
unsigned int iG = char2int(g)
unsigned int r= getR(g)
unsigned int code = iP <<r
unsigned int yx = code
for(getRi(yx) >= getRi(iG))
{ yx = yx ^ (iG<<(getRi(yx) - getRi(iG)))}
code += yx
itoa(code,scode,2)
}
void main() //定义主函数
{
char data[8]="" , bds[8]="",code[16]=""
printf("数据:")
scanf("%s", data)
printf("表达式:")
scanf("%s", bds)
CRC(code,data,bds)
printf("编码:%s",code)
}
按位计算CRC采用CRC-CCITT多项式,多项式为0x11021,C语言编程时,参与计算为0x1021。当按位计算CRC时,例如计算二进制序列为1001 1010 1010 1111时,将二进制序列数左移16位,即为1001 1010 1010 1111 (0000 0000 0000 0000),实际上该二进制序列可拆分为1000 0000 0000 0000 (0000 0000 0000 0000) + 000 0000 0000 0000 (0000 0000 0000 0000) + 00 0000 0000 0000 (0000 0000 0000 0000) + 1 0000 0000 0000 (0000 0000 0000 0000) + ……现在开始分析运算:
<1>对第一个二进制分序列求余数,竖式除法即为0x10000 ^ 0x11021运算,后面的0位保留;
<2>接着对第二个二进制分序列求余数,将第一步运算的余数*2后再和第二个二进制分序列一起对0x11021求余,这一步理解应该没什么问题。如果该分序列为0,无需计算。
<3>对其余的二进制序列求余与上面两步相同。
<4>计算到最后一位时即为整个二进制序列的余数,即为CRC校验码。
该计算方法相当于对每一位计算,运算过程很容易理解,所占内存少,缺点是一位一位计算比较耗时。
下面给出C语言实现方法:
代码如下:
unsigned char test[16] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff}
unsigned char len = 16
void main( void )
{
unsigned long temp = 0
unsigned int crc
unsigned char i
unsigned char *ptr = test
while( len-- ) {
for(i = 0x80i != 0i = i >>1) {
temp = temp * 2
if((temp &0x10000) != 0)
temp = temp ^ 0x11021
if((*ptr &i) != 0)
temp = temp ^ (0x10000 ^ 0x11021)
}
ptr++
}
crc = temp
printf("0x%x ",crc)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)