• 【校验】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;

      测试结果:

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

    知行合一
  • 相关阅读:
    linux中mysql,mongodb,redis,hbase数据库操作
    hbase数据库操作
    hdfs基本操作
    linux及hadoop基本操作
    创建有关hbase数据库的项目时所遇到的问题
    数据科学与大数据
    《TCP/IP详解卷1:协议》——第2章:链路层(转载)
    《TCP/IP详解卷1:协议》——第1章:概述(转载)
    深入理解计算机操作系统——第9章:缓存,存储器管理
    深入理解计算机操作系统——第9章:物理和虚拟寻址,地址空间
  • 原文地址:https://www.cnblogs.com/guiguzhixing/p/6058660.html
Copyright © 2020-2023  润新知