【摘 要】 信息時(shí)代,龐大的數(shù)據(jù)集合中,信息交互的出錯(cuò)在所難免。對(duì)于差錯(cuò)處理,網(wǎng)際校驗(yàn)和算法的應(yīng)用具有里程碑式的意義。算法利用網(wǎng)絡(luò)數(shù)據(jù)使用二進(jìn)制代碼的特點(diǎn),通過(guò)對(duì)信息串進(jìn)行反碼相關(guān)運(yùn)算,“放大”通信兩端數(shù)據(jù)出現(xiàn)的差異,較大程度地減少了出錯(cuò)概率。這一算法的思想如今已經(jīng)被應(yīng)用在IP、ICMP、 UDP和TCP等諸多報(bào)文的檢錯(cuò)運(yùn)算中。
本文將對(duì)網(wǎng)際校驗(yàn)的基本思想和使用情況做出簡(jiǎn)要論述,并使用python編制一個(gè)具有識(shí)別報(bào)文類(lèi)型和驗(yàn)算校驗(yàn)和功能的代碼示例。
技術(shù)上,在抓取報(bào)文時(shí)使用了網(wǎng)絡(luò)抓包軟件WireShark;識(shí)別報(bào)文類(lèi)型時(shí),依賴了python強(qiáng)大的字符串處理能力;驗(yàn)算校驗(yàn)和算法以二進(jìn)制反碼運(yùn)算為基礎(chǔ)。
【關(guān)鍵詞】 網(wǎng)際校驗(yàn)和 IP UDP TCP ICMP 二進(jìn)制 反碼運(yùn)算 互聯(lián)網(wǎng)
一、網(wǎng)際校驗(yàn)和算法
(一)算法概述
一般的網(wǎng)際校驗(yàn)和算法過(guò)程分為兩步。
第一步是,對(duì)報(bào)文分段進(jìn)行二進(jìn)制反碼加法運(yùn)算。對(duì)于需要檢測(cè)的報(bào)文部分,在發(fā)送方,先將被檢測(cè)報(bào)文的對(duì)應(yīng)校驗(yàn)和字段置為全0,繼而把該部分內(nèi)容以16位為一個(gè)單位分組,再將這些分組分別進(jìn)行二進(jìn)制反碼加法運(yùn)算,將得到的結(jié)果存入到對(duì)應(yīng)校驗(yàn)和字段,覆蓋掉全0。發(fā)送方將這樣的報(bào)文發(fā)送出去。
第二步,在接收方,將收到的報(bào)文部分以和第一步中同樣方式分段進(jìn)行二進(jìn)制反碼的加法運(yùn)算。這個(gè)時(shí)候,得到結(jié)果要么是全0要么是全1。為什么呢?
我們以IP數(shù)據(jù)報(bào)為例,假設(shè)IP數(shù)據(jù)報(bào)首部只有32位也就是4個(gè)字節(jié),經(jīng)16位的劃分,可分為兩個(gè)16位的字序列,我們暫稱其為A和B。(此時(shí)未填入數(shù)據(jù)的IP數(shù)據(jù)報(bào)首部校驗(yàn)和字段的值為0)則根據(jù)上述算法,此時(shí)首部校驗(yàn)和則為 A+B+0 = A+B,結(jié)果再求反。將A+B記為C,那則首部校驗(yàn)和就是 非C 。當(dāng)報(bào)文傳送到接收方,接收方再按照16位子序列去劃分報(bào)文首部,此時(shí)首部校驗(yàn)和字段是 非C,則需要計(jì)算的是A+B+ 非C = A+B+ 非(A+B) = 1(數(shù)字邏輯運(yùn)算)。也就是說(shuō),只要IP數(shù)據(jù)報(bào)首部未變,到此運(yùn)算結(jié)果必為1。(若再求反,則結(jié)果為就為0。)
(二)不同協(xié)議的報(bào)文運(yùn)算區(qū)別
網(wǎng)際校驗(yàn)和算法在不同的協(xié)議實(shí)現(xiàn)的時(shí)候,是有使用差別的。
主要分為兩方面:1.檢驗(yàn)字段范圍;2.正確的驗(yàn)證結(jié)果。
對(duì)于需要檢驗(yàn)的字段范圍,IP和ICMP報(bào)文不需要附加額外的字段,其中IP只需要檢驗(yàn)IP數(shù)據(jù)報(bào)的首部字段,ICMP則需要同時(shí)檢測(cè)首部和數(shù)據(jù)部分;TCP報(bào)文段和UDP用戶數(shù)據(jù)報(bào)檢驗(yàn)范圍都是首部加上數(shù)據(jù)部分,但是二者在進(jìn)行校驗(yàn)和運(yùn)算的時(shí)候,還需要在報(bào)文的首部前加上額外的12字節(jié)的被稱為“偽首部”的字段,作為參與運(yùn)算的一部分。但是偽首部不作為信息向上遞交。
對(duì)于正確的驗(yàn)證結(jié)果,其中IP和ICMP對(duì)最終的正確結(jié)果要求是全0,TCP和UDP對(duì)于最終正確結(jié)果的要求是全1。其實(shí)計(jì)算的原理都是一樣的,正常的經(jīng)過(guò)一輪網(wǎng)際校驗(yàn)和的運(yùn)算后結(jié)果為全1,不過(guò)在TCP和ICMP的檢驗(yàn)過(guò)程中,會(huì)將結(jié)果再次求反,于是獲得全0。
二、算法實(shí)現(xiàn)
(一)獲取報(bào)文
使用抓包工具WireShark,在上網(wǎng)時(shí)獲取到相應(yīng)的MAC幀數(shù)據(jù),并以此為基礎(chǔ)向內(nèi)解析出所含的IP數(shù)據(jù)報(bào)、TCP報(bào)文段或者UDP報(bào)文段。。
限于篇幅,測(cè)試數(shù)據(jù)在此不詳細(xì)列出,請(qǐng)感興趣的讀者自行嘗試抓包。
(二)區(qū)分報(bào)文的方法
報(bào)文的格式與包含關(guān)系請(qǐng)讀者先了解有關(guān)資料,這里限于篇幅不再展示。
在報(bào)文都是2進(jìn)制表示的情況下,若想從MAC幀中提取完整的IP數(shù)據(jù)報(bào),取得MAC幀中(從0開(kāi)始的)第14×8位往后的數(shù)據(jù)即可。在IP中,首先判斷第72~79(“協(xié)議”字段)位的數(shù)據(jù),若是6,則表示TCP,若是17,則表示UDP,否則表示ICMP。
對(duì)于首部檢驗(yàn)和字段,IP在第80~95位,ICMP在第16~31位置,TCP在第128~143位(不含偽首部),UDP在第48~63位(不含偽首部)。
(三)算法思路
1.獲取用戶按指定格式輸入的報(bào)文信息;
2.根據(jù)1.2中的區(qū)分報(bào)文原則,將IP數(shù)據(jù)報(bào)整體劃分出來(lái);
3.對(duì)IP首部進(jìn)行校驗(yàn)和計(jì)算,有誤則提示錯(cuò)誤,無(wú)誤則繼續(xù)提取協(xié)議字段,判斷其值;
1)若為6,則是TCP,
提取TCP報(bào)文段整體,進(jìn)行校驗(yàn)和計(jì)算,有誤則提示錯(cuò)誤,無(wú)誤則完成校驗(yàn);
2)若為17,則為UDP,
提取UDP報(bào)文段整體,進(jìn)行校驗(yàn)和計(jì)算,有誤則提示錯(cuò)誤,無(wú)誤則完成校驗(yàn);
3)不是6或17,則為ICMP,
提取ICMP報(bào)文段整體,進(jìn)行校驗(yàn)和計(jì)算,有誤則提示錯(cuò)誤,無(wú)誤則完成校驗(yàn)。
使用Python語(yǔ)言完成了本次編碼。
(四)關(guān)鍵代碼示例
1.報(bào)文分組
"""
對(duì)指定的字符串進(jìn)行4位一組分組,每組二進(jìn)制加法運(yùn)算
"""
def get_grouped_sum(s):
s2 = s
length = len(s2)
counter = int(length / 16)
ls = []
for i in range(0, counter):
ls.append(bin(int(s2[0: 16], 2))[2:])
s2 = s2[16:]
return get_bin_sum(ls)
2.對(duì)分組進(jìn)行二進(jìn)制反碼加法
'''
取得反碼求和運(yùn)算之結(jié)果
'''
def get_bin_sum(ls):
bin_sum = 0
for v in ls:
bin_sum = bin_sum + int(v, 2)
if len((bin(bin_sum))[2:]) > 16:
result = bin(bin_sum)[3:]
bin_sum = int(result, 2) + 1
return get_inverse(bin(bin_sum)[2:])
3.對(duì)結(jié)果進(jìn)行求反
'''
在字符串中將原碼“笨拙”地替換為反碼
'''
def get_inverse(s):
inverse = ''
d = {'0': '1', '1': '0'}
for e in s:
inverse += d[e]
return bin(int(inverse, 2))[2:].zfill(16)
【參考文獻(xiàn)】
[1] 施展. 新型互聯(lián)網(wǎng)傳輸協(xié)議的差錯(cuò)控制設(shè)計(jì)與協(xié)議一致性測(cè)試[D]. 北京:北京交通大學(xué),2018
[2] 謝希仁. 計(jì)算機(jī)網(wǎng)絡(luò)(第七版)[M].北京:電子工業(yè)出版社,2017:96,128,209-210,216-217
[3] Zed A. Shaw. “笨方法”學(xué)Python3 [M].北京:中國(guó)郵電出版社,2018:98
作者簡(jiǎn)介:劉楊(1999——)男,漢族,河南信陽(yáng)人,單位:河南大學(xué)計(jì)算機(jī)與信息工程學(xué)院,本科,軟件工程專(zhuān)業(yè),軟件工程: