TCP/IP 中校验和的计算方法

读《TCP/IP详解》时候看到IP首部校验和算法中叫做“每16bit反码求和”,于是我以为是每一部都先反码在求和。所以我写的过程如下:(以如下数组为例 unsigned short a[10] = { 0x4500, 0x059a, 0x82b9, 0x4000, 0x3206, 0x4f79,0xa66f, 0x08ee, 0xc0a8,  0x0126};因为IP首部长20B,就是10个16进制数,这是校验和的验证部分)

  1. unsigned short re = 0;

  2. for(int i = 0; i < 10; i++)
  3.    re += ~a[i];
  4. re = ~re;
这是错误的做法。(我理解“反码求和”是先反码加数再求和了)

然后我又做了如下的程序:

  1. unsigned short re = 0;
  2. for(int i = 0; i < 10; i++)
  3.     re += a[i];
  4. re = ~re;
因为这个unsigend short是基于模2的16次方(65536)计算的。结果运算还是不对。

再然后,看了资料,做了如下改进:

  1. int sum = 0;
  2. unsigned short result = 0;
  3. for(int i = 0; i < 10; i++)
  4. {
  5.     sum += a[i];
  6.     sum = sum % 65535;
  7. }
  8. result = (unsigned short)sum;
  9. result = ~result;

这次,result的结果是0xffff,全1,说明校验和正确了。

原来,这个反码的十进制算法是基于(2的n次方-1)的,就是说,16位的反码算术是65536-1= 65535的(65536是2的16次方),那么以上的过程就是“先求部分和,再求其反码”,或者反过来理解“先求和的反码,再求和”,简称就是反码求和了。

而上面第二个程序是unsinged short 的加法运算,默认是模65536的,所以不正确。

至于第一个程序,是我理解有误的原因,语文和英文学不好的后果,汗,所以要学好语文和英文哦。
发布了54 篇原创文章 · 获赞 16 · 访问量 34万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章