ip首部校驗和的計算方法(c語言實現)

2021-09-24 19:59:26 字數 1466 閱讀 7068

關聯部落格: 關於ip報文校驗和一些思考

把校驗和字段清零。

然後對每16位(2位元組)進行二進位制反碼求和,反碼求和的意思是先對每16位求和,再將得到的和轉為反碼。 **實現如下

short checksum

(ushort* buffer, int size)

if(size)

cksum = (cksum>>16) + (cksum&0xffff);

cksum += (cksum>>16);

return (ushort)(~cksum);

}

引數buffer是指向16位整數的指標,剛開始指向的是ip首部的起始位址,引數size是ip首部的大小。while迴圈是將ip首部的內容以16位為單元加在一起,如果沒有整除(即size還有餘下的不足16位的部分),則加上餘下的部分,此時的cksum就是相加後的結果,這個結果往往超出了16位,因為校驗和是16位的,所以要將高16位和計算得到的cksum再加工。

再加工第一步:cksum = (cksum>>16) + (cksum&0xffff); sum>>16是將高16位移位到低16位,sum&0xffff是取出低16位,相加得到新的cksum。

再加工第二步:cksum += (cksum>>16); 第一步相加時很可能會產生進製,因此要再次把進製移到低16位進行相加。    這樣就加工好了,接下來就是取反,並強制轉換為16位,這樣就得到了最終的校驗和。

校驗和計算出來了,接下來就是該如何校驗: 接收方進行校驗時,也是對每16位進行二進位制反碼求和。接收方計算校驗和時的首部與傳送方計算校驗和時的首部相比,多了乙個傳送方計算出來的校驗和。因此,如果首部在傳輸過程中沒有發生差錯,那麼接收方計算的結果應該為全一,因為接收方計算除校驗和以外的部分得到值是校驗和的反碼,再加多出來的校驗和當然是全一了。

最後對上述過程舉個例子:

ip頭:

450000

3189 f5 00

006e 06

0000(校驗字段)

de b7 45

5d -> 222.183

.69.93

c0 a8 00 dc -> 192.168

.0.220

計算:

4500 + 0031 +89f5 + 0000 + 6e06+ 0000 + deb7 + 455d + c0a8 + 00dc =3

22c4

0003 + 22c4 = 22c7

~22c7 = dd38 ->即為應填充的校驗和

當接受到ip資料報時,要檢查ip頭是否正確,則對ip頭進行檢驗,方法同上:

4500 + 0031 +89f5 + 0000 + 6e06+ dd38 + deb7 + 455d + c0a8 + 00dc =3 fffc

0003 + fffc = ffff

得到的結果是ffff,正確。

IP首部校驗和字段計算方法

ip首部有16bit的校驗和,因此,ip首部以16bit為單位計算校驗和,ip首部的長度一定是16bit的整倍數,這是由於首部長欄位是以32bit為單位計算的,不足的補0。傳送方計算方法 1.首先把校驗和的16bit置0。2.將首部以16bit為單位異或 或模2加,結果相同 3.將異或結果取反,並填...

ip首部校驗和計算

ip首部校驗和的計算方法 1.把校驗和字段清零。2.然後對每16位 2位元組 進行二進位制反碼求和,反碼求和的意思是先對每16位求和,再將得到的和轉為反碼。接下來詳細描述反碼求和的步驟 看下面的 演算法 short checksum ushort buffer,int size if size ck...

ip首部校驗和計算

ip首部校驗和的計算方法 1.把校驗和字段清零。2.然後對每16位 2位元組 進行二進位制反碼求和,反碼求和的意思是先對每16位求和,再將得到的和轉為反碼。接下來詳細描述反碼求和的步驟 看下面的 演算法 short checksum ushort buffer,int size if size ck...