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

      测试结果:

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

    知行合一
  • 相关阅读:
    Hystrix使用说明,配置参数说明
    服务限流 -- 自定义注解基于RateLimiter实现接口限流
    Java生产环境下问题排查
    Java垃圾回收(GC)机制详解
    RabbitMQ如何解决各种情况下丢数据的问题
    JWT如何在Spring Cloud微服务系统中在服务相互调时传递
    LeetCode 117th Weekly Contest 总结
    系统设计总结
    单调栈总结
    LeetCode 116th Weekly Contest 总结
  • 原文地址:https://www.cnblogs.com/guiguzhixing/p/6058660.html
Copyright © 2020-2023  润新知