概述
一开始,私以为校验和只是简单的求和得到的结果,后来在TCP和UDP里面看到使用的校验和方式有点奇怪--二进制反码(循环进位)求和。
人类的认知过程必将从简单到复杂,看下这个二进制反码循环求和是啥子意思。以16进制示例:
1.对校验序列word1,word2...wordn的二进制表示求反码
2.对求的反码序列循环进位求和,循环进位求和的意思是指把求和的进位加到低位,可能进位有x位,把这x位表示的数字和求和结果的16位相加。
感觉好像变复杂了。没关系,二进制反码循环进位求和有以下特性:
1.求和过程先求反码再二进制循环进位求和等价于先二进制循环进位求和再对求和结果求反码。(如此大大减少求反码的次数)
2.与字节序(大端小端问题)无关。(这也许是许多协议使用这种方式求和的原因)
1 ///@func:To caculate the Checksum of data 2 ///@param: 1.nums :the number of sizeof(unsigned short int) 3 /// 4 unsigned short int WordCheckSum(const unsigned short int *data, unsigned short int nums) 5 { 6 short int index = 0; 7 unsigned int sum = 0; 8 unsigned short int checkSum ; 9 for (index = 0; index < nums;index++) 10 { 11 sum += data[index]; 12 } 13 //cout << "the sum of data is: " << hex << sum << endl; 14 checkSum = (unsigned short int)(sum & 0xffff)+(unsigned short int)(sum >> 16) ; 15 /*cout << "the checkSum of data is: " << checkSum << endl;*/ 16 return ~checkSum; 17 }
测试代码:
WORD data1[5] = { 0x1122, 0x1122, 0x1122, 0x1122, 0x1122 }; WORD data2[5] = { 0x2211, 0x2211, 0x2211, 0x2211, 0x2211 }; cout << "the CheckSum of data1 is: " << hex << WordCheckSum(data1, 5) << endl; cout << "the CheckSum of data2 is: " << hex << WordCheckSum(data2, 5) << endl;
测试结果:
可见,二进制反码求和与字节序无关。
转载于:https://www.cnblogs.com/guiguzhixing/p/6058660.html
最后
以上就是愉快糖豆为你收集整理的【校验】TCP和UDP的校验和的全部内容,希望文章能够帮你解决【校验】TCP和UDP的校验和所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复