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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章