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);
}
验证通过。
0 0
原创粉丝点击