日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言 checksum,容易被忽视的IP报头中的Checksum校验和

發(fā)布時間:2024/3/24 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言 checksum,容易被忽视的IP报头中的Checksum校验和 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

看計算機(jī)網(wǎng)絡(luò)相關(guān)的書,每次看到IP或者UDP報頭校驗和時,都一瞥而過,以為相當(dāng)簡單。可是今天一看真傻眼了,怎么算的,為什么用反碼不用補(bǔ)碼還真不知道怎么回事。

算法的C語言實現(xiàn):

unsignedshortcsum(unsignedchar *addr,intcount)

{

/* Compute Internet Checksum for "count" bytes

* beginning at location "addr".

*/

register long sum = 0;

while( count > 1 ) {

/* This is the inner loop */

sum += * (unsigned short) addr++;

count -= 2;

}

/* Add left-over byte, if any */

if( count > 0 )

sum += * (unsigned char *) addr;

/* Fold 32-bit sum to 16 bits */

while (sum>>16)

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

checksum = ~sum;

return checksum;

}

計算校驗和的算法思路:

1. 將原Checksum位置全部置0,把報頭中每16bit作為一組,當(dāng)成無符號數(shù)相加得到sum,若報頭字節(jié)數(shù)為單數(shù),則最后一個字節(jié)直接當(dāng)8bit無符號數(shù)加到前面的sum上去。

2. 對sum右移16位,并與原sum的低16位相加,得到結(jié)果重新賦給sum。

3. 直到sum的高16位為0時,再將sum取反(反碼),返回sum值作為Checksum。

接收端校驗過程:

接收到的結(jié)果再進(jìn)行一次上述計算,得到返回的值應(yīng)該為0。否則,報頭在傳輸過程中出錯。

解釋1:B + ~B = 2^16 - 1(B 為WORD),算法最后返回的是反碼(反碼求和又叫1的補(bǔ)碼(one'scomplement),而2的補(bǔ)碼就是我們通常說的補(bǔ)碼求和了)。所以接收端收到數(shù)據(jù)報后得到的校驗和為B + ~B(開始校驗和占用的兩個字節(jié)為0,現(xiàn)在更過發(fā)送端的校驗后得到~B) = 2^16 - 1(B 為WORD),返回校驗和的反碼所以就檢查校驗和是否為0即可。

那么為什么用反碼而不用補(bǔ)碼呢?

a.不依賴系統(tǒng)是大端還是小端。即無論你是發(fā)送方計算或者接收方檢查校驗和時,都不需要調(diào)用htons 或者 ntohs,直接通過上面第2節(jié)的算法就可以得到正確的結(jié)果。這個問題你可以自己舉個例子,用反碼求和時,交換16位數(shù)的字節(jié)順序,得到的結(jié)果相同,只是字節(jié)順序相應(yīng)地也交換了;而如果使用原碼或者補(bǔ)碼求和,得到的結(jié)果可能就不相同!比如補(bǔ)碼計算:0xff02 + 0x00ff 和0x02ff + 0xff00結(jié)果是不相同的, 但是對于反碼來說只是序列不同結(jié)果是相同的。

b.計算和驗證校驗和比較簡單,快速。說實話,這個沒怎么看明白,感覺在校驗和計算方面,原碼或者補(bǔ)碼求和反而更簡單一些(從C語言角度),在校驗和驗證上面,通過一樣的算法判斷結(jié)果是否為全0,確實要方便一些,所以可能從綜合考慮確實反碼求和要簡便一些。另外,IP報文在傳輸過程中,路由器經(jīng)常只修改TTL字段(減1),此時路由器轉(zhuǎn)發(fā)該報文時可以直接增加它的校驗和,而不需要對IP整個首部進(jìn)行重新計算。

總結(jié)

以上是生活随笔為你收集整理的c语言 checksum,容易被忽视的IP报头中的Checksum校验和的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。