バイナリ1の補数和演算

UDPプロトコルのチェックサムの計算

  実際、この計算原理は本質的に難しいことではありません。具体的には、バイナリの補数加算演算です。

                                          0 + 0 = 0; 0 + 0 = 0

                                          1 + 0 = 0 + 1 = 1; 1 + 0 = 0 + 1 = 1

                                          1 + 1 = 10; 1 + 1 = 10

  その中で、10分の1が次の列に加算され、最上位の1 + 1の場合、得られた10は0のまま、最下位の列に1が移動され、最下位のビットでバイナリ加算が実行されます。

  Teacher Xieの本では、送信者で15バイトのUDPデータをチェックする方法について説明しました。次に、バイナリ垂直形式をリストして結果を示しますが、その方法については説明していません。計算されます。継続的な努力の末、ついにバイナリ計算プロセス全体を作成しました。私が数学科学アカデミーのクラスにいたとき、先生は比較的単純な16進計算法について話しましたが、これは実際に比べてはるかに簡単です。さて、最初に写真を撮りましょう。

教科書で謝先生が付けたタイトルはこんな感じです。

二进制版
1001 1001 0001 0011 //伪首部源IP地址前16位
0000 1000 0110 1000 //伪首部源IP地址后16位
1010 1011 0000 0011 //伪首部目的IP地址前16位
0000 1110 0000 1011 //伪首部目的IP地址后16位
0000 0000 0001 0001 //伪首部UDP协议字段代表号17,前面8位是填充0
0000 0000 0000 1111 //伪首部UDP长度字段
0000 0100 0011 1111 //UDP头部源IP地址对应的进程端口号
0000 0000 0000 1101 //UDP头部目的IP地址对应的进程端口号
0000 0000 0000 1111 //UDP头部UDP长度字段
0000 0000 0000 0000 //UDP头部UDP检验和
0101 0100 0100 0101 //数据字段
0101 0011 0101 0100 //数据字段
0100 1001 0100 1110 //数据字段
0100 0111 0000 0000 //数据字段+填充0字段
    
十六进制版
9913        //伪首部源IP地址前16位
0868        //伪首部源IP地址后16位
AB03        //伪首部目的IP地址前16位
0E0B        //伪首部目的IP地址后16位
0011        //伪首部UDP协议字段代表号17,前面8位是填充0
000F        //伪首部UDP长度字段
043F        //UDP头部源IP地址对应的进程端口号
000D        //UDP头部目的IP地址对应的进程端口号
000F        //UDP头部UDP长度字段
0000        //UDP头部UDP检验和
5445        //数据字段
5354        //数据字段
494E        //数据字段
4700        //数据字段+填充0字段

 バイナリバージョンでは、右側の最初の列から直接垂直加算を行うことはできません。10進数での垂直加算は言うまでもなく、バイナリでの垂直加算はできません。

      正しいアプローチは次のとおりです。
      (1)最初の行と2番目の行にバイナリ補完操作を実行させます。
      上記のルールに従い、1 + 1 = 10に遭遇した場合、左隣の列の下に小さな1を書き込み(前の10進キャリー加算と同様)、キャリーがない場合は、サイド列でバイナリ補数演算を実行して数値を取得します。 、キャリーを使用してバイナリ補完操作を実行し続けます。キャリーがある場合は、最初に隣接するハイサイド列の下にキャリーの小さい1を書き込み、1桁を取得して追加します。1 + 1 = 10の場合のみです。0にどのキャリーを追加してもキャリーはありません。最初の計算でキャリーがない場合は、1が生成されたときにのみキャリーが発生します。つまり、各列について、キャリーはせいぜい1回しかないので、キャリーが列を横切るという問題を心配する必要はありません。注意すべきことは、間違った数字を書かないことです。たとえば、この論文を書く前に下書きを2回入力しましたが、それでも間違いを犯します。
      上位桁に1がある場合は、1を最下位桁に移動し、基本的に補数であるバイナリ1の補数計算を再度実行します。
      (2)1行目と2行目、3行目の結果の2進補数を計算します。
      (3)操作の結果が逆になり、チェックサムが得られます。

      16進数バージョンでは、計算量が大幅に削減されます。主な計算手順は次のとおりです。
      (1)右側の最初の列から始めて、最初の列の値を10進数で計算します。
      ここでの最初の列は107として計算され、8ビットバイナリで書き込まれると01101011です。
      (2)計算結果に応じて2分割します。左の4桁は次の列を運ぶときに加算される数字として10進数に変換され、右の4桁は最初の列の結果として16進数に変換されます。
      これは610B16で、画像はDとして誤って計算され、6は次の列の操作で追加されるオブジェクトであり、Bは最初の列の結果です。
      (3)2番目の列の結果を10進数で計算し、最初の列からのキャリーを追加して2番目の列の10進数を取得し、それを2進数に変換し、2番目のステップに従って判断します。
      ここでの2番目の列は24、6は30、つまり8ビットバイナリ形式の00011110、つまり1Eです。2番目の列の結果は1で、3番目の列の10進キャリーは1です。次に、3番目の列の結果は6であり、10進キャリーは4であると計算できます。
      (4)最上位ビットから最終小数結果を計算した後、バイナリに変換する場合、右4ビットを最終結果とし、左4ビットを次列にシフトします。前のステップ96EBで得られた結果を使用し、0010を加算して最終結果を求めます。最後のステップは間違っているので、破棄しないでください。
      最終結果は96EDです。
      (5)結果を反転してチェックコードを取得します。
      チェックコードは6912です。

      さて、今回はこの特定の問題の解決策を最初に提案しました。時間があれば、コンピューターの元のコード、逆コード、および補数に関する知識を整理する必要があります。

おすすめ

転載: blog.csdn.net/qq_36171263/article/details/100335730