CRC-8
来源:互联网 发布:淘宝代销怎么取消关联 编辑:程序博客网 时间:2024/06/04 23:56
这两天因为调试一个I2C驱动,数据传输中包含了CRC校验,所以有必要对接受的数据进行校验对比。也因为这样,在网上搜索了一下,找到了一些可以使用的CRC-8算法,记录下来,方便以后使用。
CRC8的算法实现,pmbus CRC-8 x8+x2+x1+1 0x07
简计式 为生成多项式去除最高位的二进制表示,CRC函数可以理解为输入为,待校验数据流和生成多项式
输出就是CRC校验码,CRC-N表示生成的校验码的位数,N也是生成多项式的最高位数。
名称 生成多项式 简记式* 标准引用
CRC-4 x4+x+1 3 ITU G.704
CRC-8 x8+x5+x4+1 0x31
CRC-8 x8+x2+x1+1 0x07
CRC-8 x8+x6+x4+x3+x2+x1 0x5E
CRC-12 x12+x11+x3+x+1 80F
CRC-16 x16+x15+x2+1 8005 IBM SDLC
CRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS
CRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS
CRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP
1,最简单,速度最慢,占用内存最少
ptr是待校验数据流的起始地址,len是待校验数据流的字节长度,key是生成多项式的简记式
unsigned char CRC8(unsigned char *ptr, unsigned char len,unsigned char key)
{
unsigned char i;
unsigned char crc=0;
while(len--!=0)
{
for(i=0x80; i!=0; i/=2)
{
if((crc&0x80)!=0) {crc*=2; crc^=key;} /* 余式CRC 乘以2 再求CRC */
else crc*=2;
if((*ptr&i)!=0) crc^=key; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}
该算法经过验证,可以使用。
/* 方法 2 半字节查表法*/
/* 函数名:mK_cRctable
* 功能 :生成0-15对应的CRC校验码,其实就是计算机算法
*
* */
unsigned char CRC8HalfTable[16];
void mK_cRctable(unsigned char * cRctable_8, unsigned char key)
{
unsigned char cRc_8=0;
unsigned char i,j;
for(i=0;i<16;i++)
{
cRc_8 = i;
for(j=8;j>0;j--)
{
if(cRc_8&0x80)
cRc_8=(cRc_8<<1)^key;
else
cRc_8<<=1;
}
cRctable_8[i] = cRc_8;
}
}
/* 函数名:GetCrc_8
* 功能 :计算数据流* pData的16位CRC校验码,数据流长度为nLength
* */
unsigned char GetCrc_8(unsigned char * ptr, int len, unsigned char * PMBUS_CRC8_Table)
{
unsigned char crc;
unsigned char da;
crc=0;
while(len--!=0)
{
da=crc/16; /* 暂存CRC 的高四位 */
crc<<=4; /* CRC 右移4 位,相当于取CRC 的低12 位)*/
crc^=PMBUS_CRC8_Table[da^(*ptr/16)]; /* CRC 的高4 位和本字节的前半字节相加后查表计算CRC,然后加上上一次CRC的余数 */
da=crc/16; /* 暂存CRC 的高4 位 */
crc<<=4; /* CRC 右移4 位, 相当于CRC 的低12 位) */
crc^=PMBUS_CRC8_Table[da^(*ptr&0x0f)]; /* CRC 的高4位和本字节的后半字节相加后查表计算CRC,然后再加上上一次CRC的余数 */
ptr++;
}
return(crc);
}
验证通过。
/* 方法3 字节查表法 */
/* 函数名:mK_cRctable_256
* 功能 :生成0-255对应的CRC校验码,其实就是计算机算法
*
* */
unsigned char CRC8Table[256];
void mK_cRctable_256(unsigned char * cRctable_8, unsigned char key)
{
unsigned char cRc_8=0;
unsigned char j;
unsigned int i;
for(i=0;i<256;i++)
{
cRc_8 = i;
for(j=8;j>0;j--)
{
if(cRc_8&0x80)
cRc_8=(cRc_8<<1)^key;
else
cRc_8<<=1;
}
cRctable_8[i] = cRc_8;
}
}
unsigned char cal_crc(unsigned char *ptr, unsigned char len)
{
unsigned char crc=0;
while(len--!=0)
{
crc =CRC8Table[crc ^ *ptr++];
}
return(crc);
}
验证通过。
CRC8的算法实现,pmbus CRC-8 x8+x2+x1+1 0x07
简计式 为生成多项式去除最高位的二进制表示,CRC函数可以理解为输入为,待校验数据流和生成多项式
输出就是CRC校验码,CRC-N表示生成的校验码的位数,N也是生成多项式的最高位数。
名称 生成多项式 简记式* 标准引用
CRC-4 x4+x+1 3 ITU G.704
CRC-8 x8+x5+x4+1 0x31
CRC-8 x8+x2+x1+1 0x07
CRC-8 x8+x6+x4+x3+x2+x1 0x5E
CRC-12 x12+x11+x3+x+1 80F
CRC-16 x16+x15+x2+1 8005 IBM SDLC
CRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS
CRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS
CRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP
1,最简单,速度最慢,占用内存最少
ptr是待校验数据流的起始地址,len是待校验数据流的字节长度,key是生成多项式的简记式
unsigned char CRC8(unsigned char *ptr, unsigned char len,unsigned char key)
{
unsigned char i;
unsigned char crc=0;
while(len--!=0)
{
for(i=0x80; i!=0; i/=2)
{
if((crc&0x80)!=0) {crc*=2; crc^=key;} /* 余式CRC 乘以2 再求CRC */
else crc*=2;
if((*ptr&i)!=0) crc^=key; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}
该算法经过验证,可以使用。
/* 方法 2 半字节查表法*/
/* 函数名:mK_cRctable
* 功能 :生成0-15对应的CRC校验码,其实就是计算机算法
*
* */
unsigned char CRC8HalfTable[16];
void mK_cRctable(unsigned char * cRctable_8, unsigned char key)
{
unsigned char cRc_8=0;
unsigned char i,j;
for(i=0;i<16;i++)
{
cRc_8 = i;
for(j=8;j>0;j--)
{
if(cRc_8&0x80)
cRc_8=(cRc_8<<1)^key;
else
cRc_8<<=1;
}
cRctable_8[i] = cRc_8;
}
}
/* 函数名:GetCrc_8
* 功能 :计算数据流* pData的16位CRC校验码,数据流长度为nLength
* */
unsigned char GetCrc_8(unsigned char * ptr, int len, unsigned char * PMBUS_CRC8_Table)
{
unsigned char crc;
unsigned char da;
crc=0;
while(len--!=0)
{
da=crc/16; /* 暂存CRC 的高四位 */
crc<<=4; /* CRC 右移4 位,相当于取CRC 的低12 位)*/
crc^=PMBUS_CRC8_Table[da^(*ptr/16)]; /* CRC 的高4 位和本字节的前半字节相加后查表计算CRC,然后加上上一次CRC的余数 */
da=crc/16; /* 暂存CRC 的高4 位 */
crc<<=4; /* CRC 右移4 位, 相当于CRC 的低12 位) */
crc^=PMBUS_CRC8_Table[da^(*ptr&0x0f)]; /* CRC 的高4位和本字节的后半字节相加后查表计算CRC,然后再加上上一次CRC的余数 */
ptr++;
}
return(crc);
}
验证通过。
/* 方法3 字节查表法 */
/* 函数名:mK_cRctable_256
* 功能 :生成0-255对应的CRC校验码,其实就是计算机算法
*
* */
unsigned char CRC8Table[256];
void mK_cRctable_256(unsigned char * cRctable_8, unsigned char key)
{
unsigned char cRc_8=0;
unsigned char j;
unsigned int i;
for(i=0;i<256;i++)
{
cRc_8 = i;
for(j=8;j>0;j--)
{
if(cRc_8&0x80)
cRc_8=(cRc_8<<1)^key;
else
cRc_8<<=1;
}
cRctable_8[i] = cRc_8;
}
}
unsigned char cal_crc(unsigned char *ptr, unsigned char len)
{
unsigned char crc=0;
while(len--!=0)
{
crc =CRC8Table[crc ^ *ptr++];
}
return(crc);
}
验证通过。
0 0
- CRC-8
- CRC
- CRC
- CRC
- crc
- CRC
- CRC
- CRC
- CRC
- crc
- CRC
- CRC
- CRC
- CRC
- crc
- CRC
- CRC
- CRC
- 普通用户libreoffice字体很难看,但是root确是正常的
- HTML
- vi 字符替换
- Qt如何设置应用图标
- linux中vim和gedit中文乱码解决方法
- CRC-8
- VirtualBox虚拟机Ubuntu找不到网卡的解决方法[转]
- alsa 和 oss 声音系统[转]
- linux mp3乱码
- Spark-Sql之DataFrame实战详解
- dojo CheckBox问题解析
- iOS的开发中的错误解决方案
- [LeetCode]047-Permutations II
- 屏幕适配