关于CRC的简单总结
来源:互联网 发布:清华大学刘树红 知乎 编辑:程序博客网 时间:2024/05/22 14:24
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码
直接上代码:
/////////////////////////////////////////////*Author:闲云Time:2012/04/06转载或使用该代码,请注明出处,谢谢。。。*/////////////////////////////////////////////
void CCRC24Dlg::OnBtnCalCrc24() {// TODO: Add your control notification handler code hereUpdateData(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
00101 00000
10100 000
11001____________
01101 000
11010 00
11001____________
00011 00
1100
1100即为模2除法的最终余数
所以最终CRC码为:0101 1001 0000 1100
如果算法有不对的地方,还望高手指点下。。。
- 关于CRC的简单总结
- 关于CRC校验的代码
- 关于crc的算法分析
- 关于crc
- 一个关于10M以太网、双工协商、CRC错误等问题的实践性总结
- CRC总结
- 简单实用的单片机CRC快速算法
- 16位CRC查表法的简单使用方法
- 关于SEL的简单总结
- 关于以前的简单总结
- 关于SEH的简单总结
- 关于Handler的简单总结
- 学 CRC 原理和算法的总结
- 关于AOP的学习过程简单总结
- 关于SSH架构的简单总结
- 关于EL表达式语言的简单总结
- 关于Ajax的操作简单总结:
- 关于ORA-1652的一点简单总结
- mysql的字符串函数
- P2P之UDP穿透NAT的原理与实现
- 注册表小技巧让VisualSVN无限使用。
- 警告:‘xxxx’ 将随后被初始化
- 人生就像敲代码
- 关于CRC的简单总结
- Java实现UDP穿透NAT试验
- 适用I/O口模拟SPI通讯,如果时序受到中断的影响怎么办?
- 你编程得到升华:开发者需知的十个真理
- java对cookie的操作
- MySQL对表的复制,修改及删除
- http://poj.org/problem?id=1032
- 注册表小技巧让VisualSVN无限使用
- java 读取项目中的和磁盘上的properties文件