をずらし合計+がシフトしている右の16ビットはthis line of codeで合計:なぜICMPチェックサムは、私が(補完される前に)なぜICMPチェックサムの合計を理解するのに苦労しています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ましたこれは、チェックサムの計算について言いたいこと:1のの16ビットのもの補数は
チェックサム
チェックサムをありますは、ICMPタイプで始まるICMPメッセージの合計を補完します。 チェックサムの計算には、チェックサムフィールドはゼロにする必要があります。 全長が奇数の場合、受信データにチェックサムを計算するために0のオクテットが1つ埋め込まれます。このチェックサムは、今後 に変更される可能性があります。
算出する理由bs'
によって要求されるように、私は、理解を「全長が奇数の場合、受信されたデータは、チェックサムを計算するためのゼロの1つのオクテットでパディングされます。」
私もtotal = sum (map fromIntegral ws) :: Word32
私は、なぜこのコード行では把握することはできませんのコード行で行われ、16ビット・ワードの合計を加算理解することができます:
complement (fromIntegral total + fromIntegral (total `shiftR` 16))
その+ fromIntegral (total `shiftR` 16)
をすべて含める必要があります。
注:リンクされたコード行で行われたようにtotal + total `shiftR` 16
を補完すると、チェックサムが正しいことがwiresharkによって確認されています。だから私はそれが正しいことを知っている、私はちょうど理由を理解していない。
として「キャリーの周りに終わる」を計算することができます。また、この回答を見つけようとしている間、私はしばらく時間を費やしていました。後ろ向きの視界ではリンクが見えているようですが、他の人が同じように検索します。 –
これは問題ありません。[クローズされた重複は削除されません](https:// meta。stackexchange.com/a/10844/229359)他の誰かがそれを同じように見つけることができます。 – Cactus