首先,我當(dāng)你看過書,但是比較懵。
1,實例說明Checksum(校驗和)的計算步驟
直奔主題,分析一下這個Checksum(校驗和)怎么算出來的。
先用Wireshark隨便抓一個UDP或TCP包分析一下。
如上面,我們得到IP幀頭部實際數(shù)據(jù)(十六進(jìn)制):
45 00 00 34 fd 34 40 00 80 11 79 46 c0 a8 63 64 31 07 2f 2a
我們看到Wireshark分析出來的Header Checksum是0x7946,下面我們計算驗證一下。
Step1:根據(jù)IPv4頭部格式,我們知道第11和12個字節(jié)是要填寫的Checksum,先把這兩個字節(jié)都設(shè)置為0,得到
45 00 00 34 fd 34 40 00 80 11 00 00 c0 a8 63 64 31 07 2f 2a
Step2:每兩個字節(jié)組成一個數(shù)字,然后累加
4500 + 0034 + fd34 + 4000 + 8011 + 0000 + c0a8 + 6364 + 3107 + 2f2a =3 86B6
提示:可以把整個算式連同等號粘貼到Windows計算器(程序員模式,HEX方式)能得到結(jié)果。
Step3:把后面兩個字節(jié)組成的數(shù)字86B6 和 進(jìn)位3相加,上面的 3 86B6,分開兩個數(shù)相加就是
3 + 86B6 = 86B9,一般是寫成 86B6 + 3 = 86B9
Step4:取反
~(86B9)=~(1000 0110 1011 1001)=0111 1001 0100 0110=7946
?(十六進(jìn)制?。?/p>
所以得到Checksum是0x7946?是對的。
上面是發(fā)送端計算出checksum的過程。
下面是接收端校驗的過程:
接收到得到數(shù)據(jù):
45 00 00 34 fd 34 40 00 80 11 79 46 c0 a8 63 64 31 07 2f 2a
同樣也是先把checksum兩個字節(jié)先忽略(當(dāng)0000),然后每兩個字節(jié)組成一個數(shù),累加:
4500 + 0034 + fd34 + 4000 + 8011 + 0000 + c0a8 + 6364 + 3107 + 2f2a =3 86B6
進(jìn)位數(shù)加到低位,再變成
3 + 86B6 = 86B9
注:上面幾個步驟跟發(fā)送端是一樣的。
然后再加上checksum這個數(shù):
86B9
+7946=FFFF取反:~(FFFF)= 0000
結(jié)果是0000就證明沒錯。
2,解惑時刻
這本書舉例說的補碼、反碼(如下圖),跟我們開始接觸計算機(jī)學(xué)到的補碼、反碼是兩碼事!
或者你可以這么理解,這里說的數(shù)字都是無符號整數(shù),正整數(shù)的補碼就是自己,所以這里說的補碼根本不是什么補碼,就是本身;
這里說的反碼,只是簡單的按位取反!按位取反!(不是以前學(xué)的,正整數(shù)的反碼是自身,不是.)
關(guān)鍵是求和的時候,是每16位(2個字節(jié))組成一個數(shù)字 再累加的!
1E4FF怎么得來的?就是E34F+2396+4427+99F3+0000=1E4FF
接下來為什么?E4FF + 1 不是?E4FF + 2 ?因為剛才算的結(jié)果是1E4FF,進(jìn)位數(shù)是1,如果得到的結(jié)果是9E4FF,那這一步就是?E4FF + 9。(那為什么要這么加呢?這就要搬出阿貝爾群了)
接下來就是取反操作了。
大家可以看下IETF的文檔,里面甚至有C語言示例代碼。
RFC 1071 - Computing the Internet checksum
3,阿貝爾群(Abelian Group)
這里只是順便提一下。阿貝爾群概念相對簡單,就是滿足一般群的4個公理,又滿足交換律公理:
交換性(Commutativity):對于G 中任意兩個元素a,b, 滿足a?b = b?a。
這就OK了,阿貝爾群又叫交換群。
對于群的概念,要注意理解的是,中間點"?"運算符雖然被叫為"乘法",實際上,它只是代表一種運算,可以是加法,也可以是乘法,或者減法、位運算
至于上面Checksum背后的數(shù)學(xué)性質(zhì)與阿貝爾群的關(guān)系,書上有解釋,在此不贅述。
書中有句話:對于16位的十六進(jìn)制值 集合V = { 0001, ..., FFFF } 與其反碼和運算 "+"共同形成一個阿貝爾群。
——這句話的說明了,定義" + "為 二進(jìn)制反碼和? 運算,這個很關(guān)鍵。同樣,這里的反碼是按位取反的意思。
——書上說:對于V中的任何X,e + X = X + e = X,其中 e = FFFF。為什么呢?這里面有一步很關(guān)鍵的操作就是,進(jìn)位數(shù)要加到低位去,舉個栗子(都是十六進(jìn)制數(shù)為例):FFFF + 0001 = 10000,進(jìn)位為1,加到0000,結(jié)果就是0001,這才滿足e + X = X? (e = FFFF),不然你打死都不明白。文章來源:http://www.zghlxwxcb.cn/news/detail-756575.html
——這里吐槽一下書上把group翻譯為組是不對的,正確的是“群”。文章來源地址http://www.zghlxwxcb.cn/news/detail-756575.html
到了這里,關(guān)于《TCP/IP詳解 卷一:協(xié)議》第5章的IPv4數(shù)據(jù)報的Checksum(校驗和)字段的計算(這里才能解開你的困惑)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!