关于Crc校验问题,函数结果不正确

时间:2023-02-14 16:03:33
运行结果result应该为C40B,但是这个Crc校验函数得到的是660,求修改
计算CRC码的步骤为:
1、 预置16位寄存器为十六进制FFFF(即全为1)。称此寄存器为CRC寄存器;
2、 把第一个8位数据与16位CRC寄存器的低位相异或,把结果放于CRC寄存器;
3、 把寄存器的内容右移一位(朝低位),用0填补最高位,检查最低位;
4、 如果最低位为0:重复第3步(再次移位)
如果最低位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
5、 重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
6、 重复步骤2到步骤5,进行下一个8位数据的处理;
7、 最后得到的CRC寄存器即为CRC码。
8、 将CRC结果放入信息帧时,将高低位交换,低位在前。
int main(int argc, char* argv[])
{
unsigned char ch[6];
unsigned short result;
result=0xffff;
ch[0]=1;
ch[1]=3;
ch[2]=0;
ch[3]=0;
ch[4]=0;
ch[5]=2;
result=crc_check(result,ch,6);
printf("%x\n",result);
return 0;
}
int   crc_check(unsigned   short   crc,   unsigned   char *  ch,int nLen) 
{
unsigned short data;
for(int j=0 ; j<nLen ; j++)
{
data=*ch;
ch++;
crc |=((crc &0xFF)^data);   //2-   8位数据与16位CRC寄存器的低位相异或   
for(int i= 0; i<8; ++i)
{   
crc >>= 1;         //3-   寄存器的内容右移一位(朝低位) 
crc &=0x7fff;
if ((crc & 0x1)) 
crc ^= 0xA001;   //4-   如果最低位为1:CRC寄存器与多项式A001(1010   0000   0000   0001)进行异或;     
}   
    }
return   crc;  

}

25 个解决方案

#1


不是号称要自己写么?
以后咋办呢?程序的伪代码都写的很详细了,你却写不出来,以后怎么办啊?

#2


crc &0xFF
==这是干啥?把高位去掉吗?可协议中没有这么说啊,只是低位异或啊。

#3


引用 1 楼 happyparrot 的回复:
不是号称要自己写么?
以后咋办呢?程序的伪代码都写的很详细了,你却写不出来,以后怎么办啊?

嘿嘿,这个是在一个已有代码的基础上修改了一下,能明白其中意思,我感觉没问题了,但是和那个结果不符合啊,再帮我看一下吧

#4


突然想到一个事,我可以把你这个东西用来给新员工作为能力测试题。做不出来直接pass掉。

#5


引用 2 楼 happyparrot 的回复:
crc &0xFF
==这是干啥?把高位去掉吗?可协议中没有这么说啊,只是低位异或啊。
可是crc |=应该把高位又加上了吧?一开始把高位去掉,只是为了crc低位和数据异或啊,不知道我这样理解对不对?

#6


其实,我就是对2步理解不清楚,不知道异或后高位数据还要不要了,就从网上又down了代码,我觉得那样处理的话,高位又加上了啊

#7


那如果crc本身低位有数据,那么你用crc|=不就把刚异或的地位数据又改变了一次???
crc = (crc & 0xFF00) | ((crc &0xFF)^data);  

#8


晕,我这下知道原因了,糊涂了,那样不是加上高位

#9


自己好好琢磨每句话,和你对应的代码,看看是不是一个逻辑。这是你提高自己必须要做的。

#10


怎么这贴只有30分呢?刚才还100了。

#11


引用 10 楼 happyparrot 的回复:
怎么这贴只有30分呢?刚才还100了。

crc=(crc & 0xFF00) | ((crc &0xFF)^data);  加上后结果为a774还是不对啊?再帮看看啊,发完这个贴,我就剩20分了,我是新人分少啊

#12


http://topic.csdn.net/u/20091012/08/87ce2de1-9777-4561-aafd-3b1ca29b11b0.html
可以到这里领分。发帖用[救济]开头就能得到200分。

#13


还是搞不出来啊,感觉没错误了

#14


是啊。看着是对了。

#15


引用 14 楼 happyparrot 的回复:
是啊。看着是对了。
是在是找不出来了啊,告诉我吧

#16


找到了,再次移位那把

#17


??

#18


int   crc_check(unsigned   short   crc,   unsigned   char *  ch,int nLen) 
{
//unsigned short data;
unsigned char data;
for(int j=0 ; j<nLen ; j++)
{
data=*ch;
ch++;
crc=(crc & 0xFF00) | ((crc &0xFF)^data);     //2-   8位数据与16位CRC寄存器的低位相异或   
for(int i= 0; i<8; ++i)
{   
crc >>= 1;         //3-   寄存器的内容右移一位(朝低位) 
crc &=0x7fff;
/*if ((crc & 0x1)) 
crc ^= 0xA001; */  //4-   如果最低位为1:CRC寄存器与多项式A001(1010   0000   0000   0001)进行异或;     
while(!(crc & 0x1))
crc >>=1;
crc ^= 0xA001;
}   
    }
return   crc;  

}

#19


还是不行啊??大哥,天黑前告诉我吧

#20


晕。你当我不吃饭啊。

#21


我又想了一下,还是原来一开始那样正确,实在是找不出错误来了

#22


我想不会是因为最后一步,那个高低字节交换的问题吧?再给稍微指一点点明路吧

#23


我又发现一个问题,检验的是移位前的最低位,4、 如果最低位(移出去的那一位)为0,但是运行后的结果还是不符啊,鹦鹉大哥,来了吗?
int   crc_check(unsigned   short   crc,   unsigned   char *  ch,int nLen) 
{
//unsigned short data;
unsigned char data;
unsigned char btag;
for(int j=0 ; j<nLen ; j++)
{
data=*ch;
ch++;
crc=(crc & 0xFF00) | ((crc &0xFF)^data);     //2-   8位数据与16位CRC寄存器的低位相异或   
for(int i= 0; i<8; ++i)
{   
btag=crc&0x0001;
crc >>= 1;         //3-   寄存器的内容右移一位(朝低位) 
crc &=0x7fff;
if (btag) 
crc ^= 0xA001;   //4-   如果最低位为1:CRC寄存器与多项式A001(1010   0000   0000   0001)进行异或;     
}   
    }
return   crc;  

}

#24


来了。可是觉得代码没有问题啊。

#25


引用 24 楼 happyparrot 的回复:
来了。可是觉得代码没有问题啊。

呵呵,问题解决了,代码没错的,然后我在main中加上了移位,(result<<8)&0xff00| (result >> 8)& 0x00ff; 就OK了,谢啦,鹦鹉大哥。可能昨晚迷糊了,今天早晨一来就找出错误来了,呵呵

#1


不是号称要自己写么?
以后咋办呢?程序的伪代码都写的很详细了,你却写不出来,以后怎么办啊?

#2


crc &0xFF
==这是干啥?把高位去掉吗?可协议中没有这么说啊,只是低位异或啊。

#3


引用 1 楼 happyparrot 的回复:
不是号称要自己写么?
以后咋办呢?程序的伪代码都写的很详细了,你却写不出来,以后怎么办啊?

嘿嘿,这个是在一个已有代码的基础上修改了一下,能明白其中意思,我感觉没问题了,但是和那个结果不符合啊,再帮我看一下吧

#4


突然想到一个事,我可以把你这个东西用来给新员工作为能力测试题。做不出来直接pass掉。

#5


引用 2 楼 happyparrot 的回复:
crc &0xFF
==这是干啥?把高位去掉吗?可协议中没有这么说啊,只是低位异或啊。
可是crc |=应该把高位又加上了吧?一开始把高位去掉,只是为了crc低位和数据异或啊,不知道我这样理解对不对?

#6


其实,我就是对2步理解不清楚,不知道异或后高位数据还要不要了,就从网上又down了代码,我觉得那样处理的话,高位又加上了啊

#7


那如果crc本身低位有数据,那么你用crc|=不就把刚异或的地位数据又改变了一次???
crc = (crc & 0xFF00) | ((crc &0xFF)^data);  

#8


晕,我这下知道原因了,糊涂了,那样不是加上高位

#9


自己好好琢磨每句话,和你对应的代码,看看是不是一个逻辑。这是你提高自己必须要做的。

#10


怎么这贴只有30分呢?刚才还100了。

#11


引用 10 楼 happyparrot 的回复:
怎么这贴只有30分呢?刚才还100了。

crc=(crc & 0xFF00) | ((crc &0xFF)^data);  加上后结果为a774还是不对啊?再帮看看啊,发完这个贴,我就剩20分了,我是新人分少啊

#12


http://topic.csdn.net/u/20091012/08/87ce2de1-9777-4561-aafd-3b1ca29b11b0.html
可以到这里领分。发帖用[救济]开头就能得到200分。

#13


还是搞不出来啊,感觉没错误了

#14


是啊。看着是对了。

#15


引用 14 楼 happyparrot 的回复:
是啊。看着是对了。
是在是找不出来了啊,告诉我吧

#16


找到了,再次移位那把

#17


??

#18


int   crc_check(unsigned   short   crc,   unsigned   char *  ch,int nLen) 
{
//unsigned short data;
unsigned char data;
for(int j=0 ; j<nLen ; j++)
{
data=*ch;
ch++;
crc=(crc & 0xFF00) | ((crc &0xFF)^data);     //2-   8位数据与16位CRC寄存器的低位相异或   
for(int i= 0; i<8; ++i)
{   
crc >>= 1;         //3-   寄存器的内容右移一位(朝低位) 
crc &=0x7fff;
/*if ((crc & 0x1)) 
crc ^= 0xA001; */  //4-   如果最低位为1:CRC寄存器与多项式A001(1010   0000   0000   0001)进行异或;     
while(!(crc & 0x1))
crc >>=1;
crc ^= 0xA001;
}   
    }
return   crc;  

}

#19


还是不行啊??大哥,天黑前告诉我吧

#20


晕。你当我不吃饭啊。

#21


我又想了一下,还是原来一开始那样正确,实在是找不出错误来了

#22


我想不会是因为最后一步,那个高低字节交换的问题吧?再给稍微指一点点明路吧

#23


我又发现一个问题,检验的是移位前的最低位,4、 如果最低位(移出去的那一位)为0,但是运行后的结果还是不符啊,鹦鹉大哥,来了吗?
int   crc_check(unsigned   short   crc,   unsigned   char *  ch,int nLen) 
{
//unsigned short data;
unsigned char data;
unsigned char btag;
for(int j=0 ; j<nLen ; j++)
{
data=*ch;
ch++;
crc=(crc & 0xFF00) | ((crc &0xFF)^data);     //2-   8位数据与16位CRC寄存器的低位相异或   
for(int i= 0; i<8; ++i)
{   
btag=crc&0x0001;
crc >>= 1;         //3-   寄存器的内容右移一位(朝低位) 
crc &=0x7fff;
if (btag) 
crc ^= 0xA001;   //4-   如果最低位为1:CRC寄存器与多项式A001(1010   0000   0000   0001)进行异或;     
}   
    }
return   crc;  

}

#24


来了。可是觉得代码没有问题啊。

#25


引用 24 楼 happyparrot 的回复:
来了。可是觉得代码没有问题啊。

呵呵,问题解决了,代码没错的,然后我在main中加上了移位,(result<<8)&0xff00| (result >> 8)& 0x00ff; 就OK了,谢啦,鹦鹉大哥。可能昨晚迷糊了,今天早晨一来就找出错误来了,呵呵