logo资料库

CRC与IP校验和的计算.docx

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
一.CRC硬件实现。
二.Ip数据报首部检验和的程序实现。
一.CRC 硬件实现。 上次作业中用程序实现了 CRC 的算法,而计算机硬件也已经实现了 CRC 的 算法,所以需要把模二运算的过程转化为硬件容易实现的算法,目前广泛使用的 就是通过移位寄存器的移位和对应位的异或来实现 CRC 检验的,这里我用 CRC-8 做演示,其他的原理相同。 对 CRC-8 来说需要 8 个寄存器,3 个异或运算,因为 CRC-8 的生成多项式是 其中 R0 表示常数项 1,R1 表示一次项,R2 表示 2 次项 . 下图是用 visio 画的硬件寄存器实现 CRC-8 的算法示意图: 可以看到,最后原始数据 1101 经过 CRC-8 得出的 FCS 为 00100011,下面将会验 证其正确性。
我利用上次作业编写的 CRC 模二运算实现的代码检验上述硬件实现过程的正确 性,可以看到下图,经验证,它们是一致的,即正确的 FCS 就是 00100011。 二.Ip 数据报首部检验和的程序实现。 首先我利用 wireshark 抓了若干个数据报,随便点开了一个协议为 TCP 的数据报, 见以下几个图。
由上图可以看出该数据报的检验和经 wireshark 验证正确为 0x8f45. 然后我利用网络上的检验和 CheckSum 函数和自己编写的 main 函数实现对该 数据报的首部除检验和位的所有 18 个字节的输入,并计算出检验和: 程序代码如下: #include #include typedef unsigned short USHORT; typedef unsigned char UCHAR; void main() { USHORT CheckSum(USHORT *, int); int s; char iphead[50]={0x00,0x45,0x90,0x00,0x21,0x6b,0x00,0x40,0x06,0x3d,0x9b,0x73,0xd1,0x30,0x9b,0x 73,0xfa,0x2a}; //这里根据我所抓的包内首部出了检验和的所有字节对应 16 进制数放到数 组 iphead 里面。 USHORT sum; s=18; //因为这里首部为一般情况的 20 个字节,去除检验和的 2 个字节,还有 18 个字 //定义 sum 为最后的检验核数。 节,即 s 指示总字节数 18。 sum=CheckSum((USHORT*)iphead,s); printf("%x\n",sum); } USHORT CheckSum(USHORT *buffer, int size) { unsigned long cksum=0; while (size > 1) { cksum += *buffer++; size -= sizeof(USHORT); } if (size) { cksum += *(UCHAR*)buffer; //如果总字节数为奇数,则将最后一个字节用 buffer 强制转换后进行求和。 }
//对每个 16bit 进行二进制反码求和 cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); //返回最后检验和结果。 } 程序运行结果如下: 和所抓包对比可知,该检验和是正确的。
分享到:
收藏