gpt4 book ai didi

haskell - 为什么 ICMP 校验和移位 16 位

转载 作者:行者123 更新时间:2023-12-02 15:46:21 25 4
gpt4 key购买 nike

我很难理解为什么 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 对于计算校验和有这样的规定:

Checksum

The checksum is the 16-bit ones's complement of the one's complement sum of the ICMP message starting with the ICMP Type. For computing the checksum , the checksum field should be zero. If the total length is odd, the received data is padded with one octet of zeros for computing the checksum. This checksum may be replaced in the future.

我明白为什么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详细描述了校验和定义,包括这个重要部分:

On a 2's complement machine, the 1's complement sum must be computed by means of an "end around carry", i.e., any overflows from the most significant bits are added into the least significant bits.

在您的代码中,

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com