IPやUDPのパケットのチェックサムで、「チェックサムに全体の和の1の補数をいれる」理由は分かるのですが、この全体の和がなぜ1の補数の和でなければいけないのでしょうか?普通に和をとっても変わりがないように思えるのです。教えてください
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
ひとことで言えば、受信したデータのチェック(計算)が楽になるからなのですが、説明しようとするとちょっと長くなってしまいますね。(しかも、自分は何度説明を読んでも、言っている事自体は分かるが何となく腹に落ちない…)
下記に詳しい説明が載っているので、まずはご一読の上、幾つかの実例を挙げて実際に手計算してみると良いかもしれません。
コメントを受けて、追記致します。
すみません、リンクしたページだけでは説明が不十分でしたね。。
チェックサム計算の大元の定義である RFC1071:Computing the Internet Checksum(和訳) の説明が一番、網羅的に説明されているのですが、参考になる解説のリンクを2つ程貼り付けて置きます。
要するに、「1の補数の数学的な性質を上手く活用することで、計算速度を高めることが出来る」というのが理由です。
① CPUが最も得意(処理速度の速い)加算とビット反転しか使用しない
② 「1の補数の和」と言っても、個々の値の補数を取得してから和を計算する必要はなく、単純に和を求めてから、オーバーフローで桁あふれが発生した分を最後にまとめて最下位へ足せば良い
⇒ つまり計算量が少ない
③ 「バイト順独立」という性質により、ビッグエンディアン、リトルエンディアンというCPUのどちらのアーキテクチャにも適用できる
④ 「平行合計」(多分、並行合計が正しい)が可能という性質のため、最近主流の64bitCPUでは、4ワード(4bit)まとめて計算できる
⑤ 「逐次更新」、つまり『チェックサムを更新するために、16のビット整数の差分だけを加算すればよい』
⇒ 個人的には、これが重要だと思いますが、ルーターを通過する度にIPヘッダー部の書き換えが発生します。その際、チェックサムを再計算する必要があるのですが、1の補数を利用する方式では全体を再計算する必要はなく、修正の発生した部分の差だけを計算すれば良いので、処理速度を高めるのに有用!
他にも幾つか「高速処理」に役立つ性質があるようですが、自分は数学が苦手なのでまだ腹落ちしていません。。。ただ、上記の「原文(の和訳)」から、そういう設計上の「意図」があったということは、下記ページの解説から気づきました。
以下、参考にしたサイトです。
IP のチェックサム -- 1の補数演算 の最後に記載されている「おまけ」の部分
32ビット計算を使って行う場合、オーバフローが起きる回数は、単に上位 16ビットで表現されていますので、「シフト2発、足し算2発」(2発なのは補正の補正) で計算できてしまいます。
第10回 IPパケットの構造とIPフラグメンテーション (2/3) の「ヘッダ・チェックサム」フィールド:16bit幅の部分
途中の計算は4bytesや8bytesずつでもかまない。そのため、計算を高速化できるという特徴がある。計算方法そのものは単純である。単に固定幅でデータを足し込んで、最上位からあふれた1bit(桁上がり)を、最下位bitへ足せばよい(例:0xffff+0xffff=0x1fffeとなるので、0xfffeに1を加えて0xffffが結果となる)。
投稿2016/07/08 15:23
編集2016/07/09 07:30総合スコア5936
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/07/09 03:21
2016/07/09 07:31
2016/07/09 09:38