zoukankan      html  css  js  c++  java
  • 【校验】TCP和UDP的校验和

      一开始,私以为校验和只是简单的求和得到的结果,后来在TCP和UDP里面看到使用的校验和方式有点奇怪--二进制反码(循环进位)求和

      人类的认知过程必将从简单到复杂,看下这个二进制反码循环求和是啥子意思。以16进制示例:

      1.对校验序列word1,word2...wordn的二进制表示求反码

      2.对求的反码序列循环进位求和,循环进位求和的意思是指把求和的进位加到低位,可能进位有x位,把这x位表示的数字和求和结果的16位相加。

      感觉好像变复杂了。没关系,二进制反码循环进位求和有以下特性:

      1.求和过程先求反码再二进制循环进位求和等价于先二进制循环进位求和再对求和结果求反码。(如此大大减少求反码的次数)

      2.与字节序(大端小端问题)无关。(这也许是许多协议使用这种方式求和的原因)

     1 ///@func:To caculate the Checksum of data
     2 ///@param:    1.nums :the number of sizeof(unsigned short int)
     3 ///
     4 unsigned short int WordCheckSum(const unsigned short int *data, unsigned short int nums)
     5 {
     6     short int index = 0;
     7     unsigned int sum = 0;
     8     unsigned short int checkSum ;
     9     for (index = 0; index < nums;index++)
    10     {
    11         sum += data[index];
    12     }
    13     //cout << "the sum of data is: " << hex << sum << endl;
    14     checkSum = (unsigned short int)(sum & 0xffff)+(unsigned short int)(sum >> 16) ;
    15     /*cout << "the checkSum of data is: " << checkSum << endl;*/
    16     return ~checkSum;
    17 }

      测试代码:

    WORD data1[5] = {
            0x1122, 0x1122, 0x1122, 0x1122, 0x1122
        };
        WORD data2[5] = {
            0x2211, 0x2211, 0x2211, 0x2211, 0x2211
        };
        cout << "the CheckSum of data1 is: " << hex << WordCheckSum(data1, 5) << endl;
        cout << "the CheckSum of data2 is: " << hex << WordCheckSum(data2, 5) << endl;

      测试结果:

      可见,二进制反码求和与字节序无关。

    知行合一
  • 相关阅读:
    实现主从关系Form中汇总行金额/数量
    Custom.pll : 客制化菜单
    XML publisher 填充空白行数
    PLSQL提交带有模板的报表的方法
    使用Form个性化修改标准Form的LOV2
    在开发Form表单中的三种查询方法
    S3C2440 I2C实现
    NBOOT 基于VS2005的编程与编译(一)
    WINCE 6.0 调大image config.bib
    少用的defined,注意不是define
  • 原文地址:https://www.cnblogs.com/guiguzhixing/p/6058660.html
Copyright © 2011-2022 走看看