码迷,mamicode.com
首页 > 其他好文 > 详细

校验和计算方法

时间:2018-10-17 15:40:43      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:sum   字段   情况   pre   增加   icm   进制   str   col   

1.说明:

  [1]校验和覆盖的内容:

    IP校验和:IP首部。

    ICMP校验和:ICMP首部+ICMP数据;

    UDP、TCP校验和:首部+数据+12个字节伪首部(源IP地址、目的IP地址、协议、TCP/UDP包长)。

2.计算校验和的步骤:

  [1]把校验和字段设置为0。

  [2]把需要校验的数据看成以16位为单位的数字组成,依次进行二进制反码求和。

  [3]把得到的结果存入校验和字段中。

  另外UDP、TCP数据报的长度可以为奇数字节,因为计算时是16位为单位,所以此时计算校验和时需要在最后增加一个填充字节0(只是计算校验和用,不发送出去)。

3.接收端校验校验和步骤:

  [1]把需要校验的内容(包括校验和字段)看成以16位为单位的数字,依次进行二进制反码求和,如果结果是0表示正确,否则表示错误。

4.二进制反码求和步骤:

  [1]二进制反码求和,就是先把这两个数取反,然后求和,如果最高位有进位,则向低位进1。

  [2]另外,先取反后相加与先相加后取反,得到的结果是一样的。因此实现代码都是先相加,最后再取反。

5.实现代码:

static inline uint16_t check_sum(const uint16_t *buffer, int size)
{
    unsigned long cksum = 0;
    
    //16位为单位数字相加
    while(size>1){
        cksum += *buffer++;
        size -= sizeof(uint16_t);
    }

    //长度奇数情况
    if(size)
        cksum += *((unsigned char *)buffer);
    
    //高位有进位,进位到低位,下面两行代码保证了高16位为0。
    cksum = (cksum>>16) + (cksum&0xffff);
    cksum += (cksum>>16);
    
    //最后取反
    return (uint16_t)(~cksum);
}

 

校验和计算方法

标签:sum   字段   情况   pre   增加   icm   进制   str   col   

原文地址:https://www.cnblogs.com/ne-liqian/p/9804214.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!