(2019年2月19日注:這篇文章原先發在本身github那邊的博客,時間是2016年7月12日)git
週四要給工做室的小朋友們繼續培訓計算機網絡,要講的內容是傳輸層,因而今天就在準備相應的材料,從新看回謝希仁老師的課本過程當中又加深了一點理解,而後看到了當時碰到的第一個難點,UDP協議的校驗和的計算。github
其實本質上來講這個計算原理仍是不難的,就是一個二進制反碼求和運算,具體來講就是:$$0+0=0$$ $$1+0=0+1=1$$ $$1+1=10$$算法
其中10中的1加到了下一列去,若是是最高列的1+1,那麼獲得的10留下0,1移到最低列,與最低位再作一次二進制加法便可。bash
在謝老師的這本書裏,講到的是一個15字節的UDP數據在發送方怎麼進行數據的檢驗,而後列出了一個二進制的豎式並給出一個結果,然而並無講述是怎麼計算出來的。通過我不斷的努力,終於把二進制計算的過程整個寫出來了。以前在數計院上課的時候,老師講過一個較爲之簡單的十六進制計算法,對比之下確實是簡單不少。好了,先上圖。網絡
謝老師在課本里面給出的題目是這樣子的。計算機網絡
二進制版 1001 1001 0001 0011 //僞首部源IP地址前16位 0000 1000 0110 1000 //僞首部源IP地址後16位 1010 1011 0000 0011 //僞首部目的IP地址前16位 0000 1110 0000 1011 //僞首部目的IP地址後16位 0000 0000 0001 0001 //僞首部UDP協議字段表明號17,前面8位是填充0 0000 0000 0000 1111 //僞首部UDP長度字段 0000 0100 0011 1111 //UDP頭部源IP地址對應的進程端口號 0000 0000 0000 1101 //UDP頭部目的IP地址對應的進程端口號 0000 0000 0000 1111 //UDP頭部UDP長度字段 0000 0000 0000 0000 //UDP頭部UDP檢驗和 0101 0100 0100 0101 //數據字段 0101 0011 0101 0100 //數據字段 0100 1001 0100 1110 //數據字段 0100 0111 0000 0000 //數據字段+填充0字段 十六進制版 9913 //僞首部源IP地址前16位 0868 //僞首部源IP地址後16位 AB03 //僞首部目的IP地址前16位 0E0B //僞首部目的IP地址後16位 0011 //僞首部UDP協議字段表明號17,前面8位是填充0 000F //僞首部UDP長度字段 043F //UDP頭部源IP地址對應的進程端口號 000D //UDP頭部目的IP地址對應的進程端口號 000F //UDP頭部UDP長度字段 0000 //UDP頭部UDP檢驗和 5445 //數據字段 5354 //數據字段 494E //數據字段 4700 //數據字段+填充0字段
在二進制版中,是不能夠直接從右邊第一列開始作豎式相加的,不要說十進制的豎式相加,二進制的豎式相加都作不到。對象
正確的作法是:
(1) 讓第一行和第二行作二進制反碼運算。
根據上述的規則,當碰到1+1=10時,在左鄰側一列下面寫個小1(相似之前作十進制進位加法),而後側列進行二進制反碼運算得出一個數,若是沒有進位,就繼續與剛纔的進位作二進制反碼運算,若是有進位,則先把進位的小1寫在相鄰高側列的下方,取個位來與其相加。有進位的只有1+1=10的狀況,0不論加什麼進位都不會有進位,而若是第一次計算沒有進位時,只有產生1的狀況下才會有進位,總而言之,對於每一列,都只會有至多一次的進位,因此不用擔憂進位會跨列的問題。這樣子作要注意的就是不要寫錯數字了,好比我本身在寫這張紙以前已經打過兩次草稿了,然而仍是會寫錯。
對於高位有1的狀況,就是把1挪到最低位,再作一次二進制反碼計算,本質來講就是取補碼。
(2) 將第一行和第二行的結果與第三行作二進制反碼計算,以此類推。
(3) 運算結果取反,獲得校驗和。blog
在十六進制版中,運算量會大大減少,主要的計算步驟以下:
(1) 從右邊第一列開始,按照十進制來計算第一列的值。
在這裏第一列算出來是107,寫成8位二進制就是01101011。
(2) 根據算出來的結果分紅兩部分,左邊的4位化成十進制,做爲下一列進位時加的數,右邊4位化成16進制,做爲第一列的結果。
這裏就是610B16,圖片誤算成D,6做爲下一列運算時要加上的對象,B做爲第一列的結果。
(3) 十進制計算第二列的結果,加上第一列獲得的進位獲得第二列的一個十進制數字,化爲二進制,根據第二步來進行判斷,依次類推。
在這裏第二列算到的是24,加上6就是30,化爲8位二進制就是00011110,也就是1E,第二列的結果爲1,第三列的十進制進位爲1。接着能夠算到第三列的結果爲6,十進制進位爲4。
(4) 最高位算出最後的十進制結果後,化爲二進制時,右邊4位做爲最終結果,左邊4位移入下一列,用上一步獲得的結果96EB,加上0010,獲得最後結果,這裏圖片的最後一步寫錯了,不該該捨棄。
最後能獲得結果爲96ED。
(5) 結果取反,獲得校驗碼。
校驗碼爲6912。進程
好了此次先針對這個特定的問題提出瞭解決方案,有時間要好好整理下關於計算機的原碼、反碼和補碼的知識。圖片