關於UDP的檢驗和計算(附代碼)


關於UDP的檢驗和計算(附代碼)

在下午的學習過程中https://www.cnblogs.com/roccoshi/p/13032356.html 有一張圖講述了UDP的校驗方法, 如下:

老師只粗略的講述了檢驗過程, 並沒有講計算方法, 檢驗和 這玩意之前也多次提到過了, 每次都沒有自己算過, 剛好借此機會詳細了解記錄一下

反碼求和運算

檢驗和主要是基於反碼求和運算:

反碼算數運算:兩個數進行二進制反碼求和的運算很簡單。它的規則是從低位到高位逐列進行計算。0和0相加是0,0和1相加是1,1和1相加是0,但要產生一個進位1,加到下一列。如果最高位相加后產生進位,則最后得到的結果要加1。

之前在操作檢驗和的過程中, 我一直有一個誤解, 那就是計算時都把數據當成源碼, 取反再進行上述規則的運算

但其實不是這樣的, 數據本身就以"反碼"形式存在, 直接按此規則計算即可.

簡單來說, 對於圖中的檢驗和計算過程, 就是這樣的:

把數據視為無符號16位整數相加, 如果產生了進位,則需要額外加1

此處需要注意的是: 任何兩個數進行反碼求和產生進位, 將進位去除額外加一后不會產生新的進位了. 這里可以自行驗證:

比如4位無符號反碼最大有1111+1111得到11110, 將進位加到末尾即1111不會再產生新進位

python代碼計算

經過上面的分析, 直接給出計算圖中檢驗和的python代碼:

def checksum(data):
	s = 0
	for i in data:
		s += i
		s = (s & 0xffff) + (s >> 16) # 取前16位,然后將17位(進位的值加到第一位上)
	return (~s & 0xffff)


if __name__ == '__main__':
	data = [0b1001100100010011,0b0000100001101000,0b1010101100000011,0b0000111000001011,
			0b0000000000010001,0b0000000000001111,0b0000010000111111,0b0000000000001101,
			0b0000000000001111,0b0000000000000000,0b0101010001000101,0b0101001101010100,
			0b0100100101001110,0b0100011100000000]
	check = checksum(data) # 檢驗和的值
	data[9] = eval(bin(check)) # 將檢驗和對應的地方改成檢驗和
	print(bin(checksum(data)))	# 再進行反碼求和,如果各位全為1,則說明檢驗通過
	if checksum(data)==0:
		print("yes")

得到的結果為:

0b0110100100010010 # 得到的checksum
0b1111111111111111 # 加入checksum后的結果,全1表示檢驗通過了
yes

參考資料
https://www.zhihu.com/question/47025566/answer/103966103
https://www.bilibili.com/video/BV19E411D78Q?p=62


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM