This question already has answers here:
Bit shifting in internet checksums
(3 个回答)
4年前关闭。
我正在努力理解为什么 ICMP 校验和总数(在被补充之前)是 this line of code 中的总数 + 右移 16 位总数:
RFC 792 关于计算校验和有这样的说法:
我理解为什么要计算
我也可以理解对这行代码
我只是无法弄清楚为什么在这行代码中:
注意:我已经使用wireshark 验证了校验和只有在我像链接的代码行中所做的那样补充
是 32 位和,即它的低 16 位是没有进位的和,高 16 位将包含进位的和。通过使用
所以我们可以计算“结束进位”为
(3 个回答)
4年前关闭。
我正在努力理解为什么 ICMP 校验和总数(在被补充之前)是 this line of code 中的总数 + 右移 16 位总数:
checksum bs = let bs' = (if (BL.length bs) `mod` 2 == 0 then bs else BL.snoc bs 0)
ws = runGet listOfWord16 bs'
total = sum (map fromIntegral ws) :: Word32
in complement (fromIntegral total + fromIntegral (total `shiftR` 16))
RFC 792 关于计算校验和有这样的说法:
我理解为什么要计算
bs'
,因为“如果总长度为奇数,则接收到的数据将填充一个八位字节的零以计算校验和。”我也可以理解对这行代码
total = sum (map fromIntegral ws) :: Word32
中完成的 16 位字的总和进行求和我只是无法弄清楚为什么在这行代码中:
complement (fromIntegral total + fromIntegral (total `shiftR` 16))
+ fromIntegral (total `shiftR` 16)
应该包括在内。注意:我已经使用wireshark 验证了校验和只有在我像链接的代码行中所做的那样补充
total + total `shiftR` 16
时才正确。所以我知道这是正确的,我只是不明白为什么。 最佳答案
RFC 1071 详细描述了校验和定义,包括这个重要部分:
在您的代码中,
total = sum (map fromIntegral ws) :: Word32
是 32 位和,即它的低 16 位是没有进位的和,高 16 位将包含进位的和。通过使用
fromIntegral :: Word32 -> Word16
进行截断的事实,我们有low = fromIntegral total :: Word16
high = fromIntegral $ total `shiftR` 16 :: Word16
所以我们可以计算“结束进位”为
eac = low + high
关于haskell - 为什么 ICMP 校验和移位 16 位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44815097/
10-16 19:16