关于CRC的简单总结
2012-04-06 17:19
309 查看
CRC码的生成步骤:
1.如果需要做16位的CRC校验,则需要将x的最高次幂为16生成多项式G(X)转换成对应的17位二进制数
G(X)=1+X(1)+X(3)+X(10)+X(13)+X(15)+X(16)
对应二进制码:1 1010 0100 0000 1011
2.将信息码左移16位
3.用生成多项式(二进制数)对信息码做除,得到16位的余数,模2除法 mod(x,y)= x - y * floor(x/y)
4.将余数拼到信息码左移后空出的位置,得到完整的CRC码
直接上代码:
http://download.csdn.net/detail/nanfeiyannan/4204674
测试用例:
十六进制信息码:590--0101 1001 0000,生成项:11001
信息码左移4位补0:0101 1001 0000 0000
模2除法过程:
01011 00100000000
10110 0100000000
11001____________
01111 0100000000
11110 100000000
11001____________
00111 100000000
11110 0000000
11001____________
00111 0000000
11100 00000
11001[u]____________[/u]
00101 00000
10100 000
11001[u]____________[/u]
01101 000
11010 00
11001[u]____________[/u]
00011 00
1100
1100即为模2除法的最终余数
所以最终CRC码为:0101 1001 0000 1100
如果算法有不对的地方,还望高手指点下。。。
1.如果需要做16位的CRC校验,则需要将x的最高次幂为16生成多项式G(X)转换成对应的17位二进制数
G(X)=1+X(1)+X(3)+X(10)+X(13)+X(15)+X(16)
对应二进制码:1 1010 0100 0000 1011
2.将信息码左移16位
3.用生成多项式(二进制数)对信息码做除,得到16位的余数,模2除法 mod(x,y)= x - y * floor(x/y)
4.将余数拼到信息码左移后空出的位置,得到完整的CRC码
直接上代码:
//////////////////////////////////////////// /* Author:闲云 Time:2012/04/06 转载或使用该代码,请注明出处,谢谢。。。 */ ////////////////////////////////////////////
void CCRC24Dlg::OnBtnCalCrc24() { // TODO: Add your control notification handler code here UpdateData(TRUE); CString strTips; strTips=CRC24(m_strMD,m_strGD); MessageBox(strTips); } /*//////////////////////////////////////////////////////////////////////// 功能:十六进制转为十进制 输入:char chData//需要转换的十六进制数,结合本需求,只考虑了一位的 输出:int iDataTemp//转换后的十进制数 ////////////////////////////////////////////////////////////////////////*/ int CCRC24Dlg::HexTODec(char chData) { int iDataTemp=0; if('0'<=chData&&chData<='9'){ iDataTemp=chData+iDataTemp*16-'0'; } else if('a'<=chData&&chData<='z'){ iDataTemp=chData+iDataTemp*16-'a'+10; } else if('A'<=chData&&chData<='Z'){ iDataTemp=chData+iDataTemp*16-'A'+10; } return iDataTemp; } /*//////////////////////////////////////////////////////////////////////// 功能:十进制转为二进制 输入:int iDecData//需要转换的十进制数 输出:CString strData//转换后的二进制字符串 ////////////////////////////////////////////////////////////////////////*/ CString CCRC24Dlg::DecToBin(int iDecData) { int i,iDataLen; CString strDataTemp,strData,strTemp; for(i=0;iDecData/2!=0;i++){ strTemp.Format("%d",iDecData%2); strDataTemp+=strTemp; iDecData=iDecData/2; } strTemp.Format("%d",iDecData); strDataTemp+=strTemp; iDataLen=strDataTemp.GetLength(); for (i=4;i>iDataLen;i--) { strData+="0"; } for (i=0;i<iDataLen;i++) { strData+=strDataTemp[iDataLen-i-1]; } return strData; } /*//////////////////////////////////////////////////////////////////////// 功能:清除二进制字符串中第一位不为1的位 输入:CString strTemp//被处理前的二进制字符串 输出:CString strTemp//被处理后的二进制字符串 ////////////////////////////////////////////////////////////////////////*/ CString CCRC24Dlg::InitClear(CString strTemp) { for (int j=0;j<strTemp.GetLength();j++) { if (strTemp[j]=='1') { strTemp=strTemp.Right(strTemp.GetLength()-j); break; } else if (j==strTemp.GetLength()-1) { strTemp="2"; } } return strTemp; } /*//////////////////////////////////////////////////////////////////////// 功能:异或运算 输入:CString strData1//做异或运算的第一个二进制字符串 CString strData2//做异或运算的第二个二进制字符串 int lenGD//异或运算的位数;除数的位数;CRC的生成项的位数 输出:CString strResult//异或运算后的二进制字符串 ////////////////////////////////////////////////////////////////////////*/ CString CCRC24Dlg::MXORD(CString strData1,CString strData2,int lenGD) { CString strResult; for (int i=0;i<lenGD;i++) { if(strData1[i] != strData2[i]) { //相异的时候为1 strResult += '1'; } else { //相同则为0 strResult += '0'; } } return strResult; } /*//////////////////////////////////////////////////////////////////////// 功能:二进制转为十六进制 输入:CString strBin//需要转换的十六进制数 //结合本需求,只考虑了一位的十六进制数 输出:char chData//转换后得到的十六进制数 ////////////////////////////////////////////////////////////////////////*/ char CCRC24Dlg::BinToHex(CString strBin) { int i=0,iDec=0; CString strHex; for(i=0;i<strBin.GetLength();i++) { iDec=strBin[i]+iDec*2-'0'; } char chData; switch(iDec%16) { case 0: chData='0'; break; case 1: chData='1'; break; case 2: chData='2'; break; case 3: chData='3'; break; case 4: chData='4'; break; case 5: chData='5'; break; case 6: chData='6'; break; case 7: chData='7'; break; case 8: chData='8'; break; case 9: chData='9'; break; case 10: chData='A'; break; case 11: chData='B'; break; case 12: chData='C'; break; case 13: chData='D'; break; case 14: chData='E'; break; case 15: chData='F'; break; } return chData; } /*//////////////////////////////////////////////////////////////////////// 功能:计算CRC24 输入:CString strMDHex//需要计算crc的十六进制字符串 CString strGDBin//计算crc的生成项的二进制字符串 输出:模2除法得到余数,以二进制字符串形式显示 ////////////////////////////////////////////////////////////////////////*/ CString CCRC24Dlg::CRC24(CString strMDHex, CString strGDBin) { //////////////每一位十六进制转为对应二进制//////// CString strMD; for (int i=0;i<strMDHex.GetLength();i++) { int iTemp=HexTODec(strMDHex[i]); strMD+=DecToBin(iTemp); } //////////////模2除法得到余数//////////////////// int j=0; int lenGD=strGDBin.GetLength(); CString strResultTemp,strResult; for (j=0;j<lenGD-1;j++) { strMD+="0"; } do { strMD=InitClear(strMD);//清除第一位不为1的位 strResultTemp=strMD.Left(lenGD); if ("2"==strResultTemp) { strMD.Format("%s",_T("0")); } else { strMD=strMD.Right(strMD.GetLength()-lenGD); strResultTemp=MXORD(strResultTemp,strGDBin,lenGD); strResult=strResultTemp;//最终余数 strResultTemp=InitClear(strResultTemp); if ("2"!=strResultTemp) { strResultTemp+=strMD; strMD=strResultTemp; } } } while (strMD.GetLength()>=lenGD); ///////////补位成所需要的位数///////////////////// CString strCRC,strHex; for (j=strMD.GetLength();j<lenGD-1;j++) { strCRC+="0"; } strCRC+=strMD; return strCRC; }上面的函数已经完全可以实现我们的需求了,如果你比我还懒,不要紧,现在给你Demo的下载地址:
http://download.csdn.net/detail/nanfeiyannan/4204674
测试用例:
十六进制信息码:590--0101 1001 0000,生成项:11001
信息码左移4位补0:0101 1001 0000 0000
模2除法过程:
01011 00100000000
10110 0100000000
11001____________
01111 0100000000
11110 100000000
11001____________
00111 100000000
11110 0000000
11001____________
00111 0000000
11100 00000
11001[u]____________[/u]
00101 00000
10100 000
11001[u]____________[/u]
01101 000
11010 00
11001[u]____________[/u]
00011 00
1100
1100即为模2除法的最终余数
所以最终CRC码为:0101 1001 0000 1100
如果算法有不对的地方,还望高手指点下。。。
相关文章推荐
- 关于mysql 简单的查询语句 以及常用函数的 总结
- 关于ASP.NET MVC4 Web API简单总结
- 关于ListView控件使用的个人总结--以一个简单的新闻客户端开发为例
- 【VS开发】关于SEH的简单总结
- 关于宏的一些简单总结
- 关于cvSmooth(包括简单,中值,高斯,双边)的总结
- 关于CRC循环冗余校验的总结(C#)
- 关于ORA-1652的一点简单总结
- 关于反爬虫的一些简单总结
- 关于Sqlite的简单使用与总结,可直接模仿用到现有项目中~
- 关于mysql 简单的查询语句 以及常用函数的 总结
- PHP中关于foreach的简单的用法总结
- 一个关于10M以太网、双工协商、CRC错误等问题的实践性总结
- 关于Handler的简单总结
- VBA中关于dim的简单总结
- 关于字符集,编码格式,大小端的简单总结
- 关于JS与OC交互的简单总结
- 关于ORA-1652的一点简单总结
- saltstack一些简单总结--关于salt-key命令的一些(3)
- 关于JS与OC交互的简单总结