【IT168

技术文档】一、校验和算法

之前一直只知道IP校验和算法反码求和相关的,但具体细节不清楚,今天了解了下。

IP校验和主要是用来保证数据(IP包头)的完整性的.它用的算法非常简单,就是反码求和校验.需要注意的是反码求和又叫1的补码(one'scomplement),而2的补码就是我们通常说的补码求和了.校验算法具体如下。

1、发送方

i)将校验和字段置为0,然后将IP包头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;

ii)对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位),将得到的和的反码填入校验和字段;

iii)发送数据包.

2、接收方

i)将IP包头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;

ii)对各个单元采用反码加法运算,检查得到的和是否符合是全1(有的实现可能对得到的和会取反码,然后判断最终值是不是全0);

iii)如果是全1则进行下步处理,否则意味着包已变化从而丢弃之.需要强调的是反码和是采用高位溢出加到低位的,如3比特的反码和运算:100b+101b=010b(因为100b+101b=1001b,高位溢出1,其应该加到低位,即001b+1b(高位溢出位)=010b),具体细节请参考文章:http://blog.chinaunix.net/u/20/showart_438418.html

内容导航

二、校验和源码

网上流传多组实现,常见的有如下两种(如追求效率可改写为汇编代码):

1、RFC1071源码

Code highlighting produced by Actipro

CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

unsigned short csum(unsigned char *addr,

int count)

{register long

sum = 0;while( count > 1 )

{sum +=

* (unsigned short)

addr++;

count -= 2;

}if(

count >

0 )

sum += * (unsigned char *) addr;while

(sum>>16)

sum = (sum & 0xffff)

+ (sum >>

16);return ~sum;

}

第一个while循环是做普通加法(2进制补码加法),因为IP包头和TCP整个报文段比较短(没达到2^17数量级),所以不可能导致4字节的sum溢出(unsigned

long 一般至少为4字节)).

紧接着的一个判断语句是为了能处理输入数据是奇数个字节的这种情况.再接着的数据循环是实现反码算法(在前面的普通加法得到的数据的基础上),由反码和的高位溢出加到低位的性质,可得到"32位的数据的高位比特移位16比特,再加上原来的低16比特,不影响最终结果"

这个等价运算,因为sum的最初值(刚开始循环时)可能很大,所以这个等价运算需循环进行,直到sum的高比特(16比特以上)全为0.对于32

位的 sum,事实上这个运算循环至多只有两轮,所以也有程序直接用两条"sum = (sum &

0xffff) + (sum >>

16);"代替了整个循环.最后,对和取反返回.

2、对数据长度没限制的实现

Code highlighting produced by Actipro

CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

unsigned short cksum

(struct ip *ip, int len)

{long sum =

0;while

( len >1 )

{

sum += *((unsigned short *)

ip)++;if (sum & 8x00000000)sum =

(sum & 0xFFFF)

+ (sum>>

16) ;

len -= 2;

}if ( len )sum +=

( unsigned short )

* (unsignedl char *) ip;while ( sum >>

16)

sum =(sum & 0xFFFF)

+ (sum>>

16);return ~sum;}

这个实现与前面的一个的最大的不同是对数据的长度没什么限制了,因为它在第一个循环的加法运算中实时检测sum的高位的值,一旦发现其有溢出的危险,就及时运用等价运算关系消除了这个危险.

内容导航

三、几个细节问题

1、数据部分改变时的重校验

考虑这样的应用场景:路由器转发IP报文时,有可能只更改了IP数据包头的部分内容(如更改了TTL,分片了或SNAT更改了源IP等~~~),却需要重校验的问题.为提高转发效率,要求重校验算法尽可能快,故出现了如下所示的重校验算法(只是一个简单的示例):

Code highlighting produced by Actipro

CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

UpdateTTL(struct ip_hdr

*ipptr, unsigned char n)

{

unsigned long

sum;

unsigned short

old;

old = ntohs(*(unsigned short *)&ipptr->ttl);

ipptr->ttl -= n;

sum = old +

(~ntohs(*(unsigned short *)&ipptr->ttl) & 0xffff);

sum += ntohs(ipptr->Checksum);

sum = (sum & 0xffff)

+ (sum>>16);

ipptr->Checksum = htons(sum + (sum>>16));

}

算法的实现依据是这样的.假设包头原校验和为~C,改变的字段的原始值是m,更改后的值是m',设~C'为重校验和,则有

~C' = ~(C+(-m)+m') = ~C+(m-m') =

~C+m+~m'等价关系的成立基于反码的运算性质:取反运算满足结合律,按位取反运算与符号取反(及相反数)是等价的(即~C=-C).

如果有多个字段改变,只是上面的公式中的m和m'有多个而已,直接用反码加法搞定即可。

2、为什么采用反码和运算

IP数据包校验要求速度快,所以只采用了简单的和校验,为什么采用反码和而不是补码和呢?

i)反码和的溢出有后效性(蔓延性)

反码和将高位溢出加到低位,导致这个溢出会对后面操作有永久影响,有后效性;而补码和直接将高位和溢出,导致这个溢出对后面的操作再无影响,因此无后效性

ii)反码校验无需考虑字节序

正因为反码和的溢出有后效性,导致大端字节序(big-endian)和小端字节序(little-endian)对同一数据序列(如两个16比特的序列)产生的校验和也只是字节序相反,而补码和因为将溢出丢掉了,不同字节序之间的校验和大不相同且没什么联系。

基于以上的理由,校验和运算既可选择在数据被转换成网络字节序前,也可选择在之后,只要保证被校验的字段和填写的校验和字段的字节序保持一致就可以了。(这其实可以看作是负负得正,计算校验和与字节序有关,然后写校验和字段与字节序有关,然后直接计算校验和再写校验和字段则与字节序无关。)

四、参考文章

http://blog.chinaunix.net/u/20/showart_438512.html,关于IP校验和的

http://blog.chinaunix.net/u/12313/showart_176114.html,关于网络校验和的

http://www.wesoho.com/article/Delphi/2143.htm,关于IP校验和的

http://blog.chinaunix.net/u/20/showart_438418.html,关于补码和反码的

计算机网络反码求和代码,IP校验与算法反码求和详解相关推荐

  1. 字符串匹配代码C语言,KMP算法(快速模式匹配算法)详解以及C语言实现

    通过上一节的介绍,学习了普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个过程称为"指针回溯&q ...

  2. 【5G/4G】加/解密+完整性保护/校验算法源码详解

    文章目录 加/解密+完整性保护/校验算法源码详解 一.加解密算法 二.完整性保护/校验算法 本人就职于国际知名终端厂商,负责modem芯片研发. 在5G早期负责终端数据业务层.核心网相关的开发工作,目 ...

  3. 【计算机网络】CRC校验码||循环冗余码详解及计算习题

    [计算机网络]CRC校验码||循环冗余码详解及计算习题

  4. OSI 七层模型和TCP/IP模型及对应协议(详解)

    OSI 七层模型和TCP/IP模型及对应协议(详解) 查看全文 http://www.taodudu.cc/news/show-6185847.html 相关文章: OSI7层网络模型协议精析 OSI ...

  5. c语言实现sha1算法注解,【密码学】SHA1算法实现及详解

    1 SHA1算法简介 安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digit ...

  6. python如何调用文件进行换位加密_python 换位密码算法的实例详解

    python 换位密码算法的实例详解 一前言: 换位密码基本原理:先把明文按照固定长度进行分组,然后对每一组的字符进行换位操作,从而实现加密.例如,字符串"Error should neve ...

  7. 【算法知识】详解堆排序算法

    点击蓝色字关注我们! 什么是堆 「堆」首先是一个完全二叉树,「堆」分为「大顶堆」和「小顶堆」: 「大顶堆」 : 每个节点的值大于或等于其左右孩子节点的值,称为大顶堆. 「小顶堆」同理就是每个节点的值小 ...

  8. 【算法知识】详解基数排序算法

    已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 [算法知识]详解归并排序算法 基本思想 基数排序的思想是将整数按位数切 ...

  9. 【算法知识】详解归并排序算法

    已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 基本思想 归并排序的基本思想是: 先将序列一次次分成子序列,直到子序列 ...

最新文章

  1. iOS SwiftUI篇-1 项目结构
  2. PHP正则匹配到2个字符串之间的内容,匹配HTML便签内容
  3. 贪心 or 动态规划 求解“最大字段和”问题(洛谷P1115题题解,Java语言描述)
  4. elasticsearch x-pack license过期
  5. C语言实现2048小游戏
  6. 中国税负68%,世界排名12
  7. LabVIEW学习笔记(1)
  8. 2015计算机一级试题及答案,2015年全国计算机等级考试一级试题及答案【精编直接打印版】.doc...
  9. MFC调用RDP实现远程桌面共享实例
  10. tomcat jquery mysql_Docker 搭建 Tomcat + Mysql
  11. 预告 ARC 重写:iOS 实现的 json 数据源的 O-R Mapping
  12. 游戏爱好者如何选购计算机,通俗易懂,游戏本该怎么挑
  13. 达梦数据库:备份 冷备与热备
  14. 淘宝关键词API接口、1688、京东、拼多多平台商品信息获取采集
  15. 杭州中高级职称评审流程
  16. Zzzzzz 每天来点负能量---看着就会心地笑了
  17. JAVA JSP水费管理系统JSP电费管理系统JSP缴费管理系统JSP水费缴费系统JSP水电费管理
  18. BLAG: Improving the Accuracy of Blacklists
  19. 苏州文正学院计算机张晓青,北流市地图(广西政区图地图)
  20. 鸿蒙系统开发实战-开发一个聊天技巧软件堪称聊天神器

热门文章

  1. 排查解决腾讯云服务器存在对外攻击行为,已阻断该服务器对其他服务器端口(TCP:6379)的访问
  2. mysql 1067 datadir_MySQL修改datadir后启动服务发生1067错误的解决办法
  3. 81-MySQL(表锁,行锁,排他锁,共享锁)
  4. 拍七游戏 许多人都曾经玩过“拍七”游戏。 规则是:大家依次从1开始顺序数数,数到含有7或7的倍数的要拍手或其它规定的方式表示越过 (比如:7,14,17等都不能数出),下一人继续数下面的数
  5. Google测试之道 - 谷歌测试工具
  6. 香橙派嵌入式arm开发板下载交叉编译工具链说明
  7. redis基础和使用篇(一)--简介
  8. 计算机室管理制度汇编,计算机实验室管理制度汇总
  9. [转]男人靠什么吸引女人
  10. 2022A特种设备相关管理(电梯)判断题及模拟考试