CRC、反码求和校验 原理分析
3月份开始从客户端转后台,算是幸运的进入全栈工程师的修炼阶段。这段时间一边是老项目的客户端加服务器两边的维护和交接,一边是新项目加加加班赶工,期间最长经历了连续工作三天只睡了四五个小时的煎熬,人生也算是完整了。。。写博客也算是又一次废了。。。
一边赶项目,一边看TCP/IP相关的书,本科学的网络知识一直都是一知半解,现在终于有机会深入研究一下了。
TCP/IP主要就是各种协议,各种接口。校验这个概念,一直都不陌生。之前在客户端用的最多的校验是MD5、CRC校验,在逻辑层网络协议,客户端文件等用的比较多。但是一直没有深究里面的原理。而网络传输用的就更多了,IP头、ICMP、TCP和UDP 都用了反码求和校验。
-------------------------分割线--------------------------
CRC校验:
设原始信息字段K位,校验字段R位,码字(最终发送信息)长度(N=K+R),则对于CRC码集中的任一码字,存在且仅存在一个R次多项式g(x),使得
v(x) = a(x)g(x) = m(x) xR + r(x)
其中m(x)是K次多项式,r(x)为R-1次校验多项式,v(x)为CRC码
也即二进制m(原始信息)左移R位,加上剩下的R位(余数),得到值v(最终发送信息),能被一个选定的二进制数g整除。发送端发送的信息,到接收端能被指定的数g整除,则信息是完整的。为了唯一性,g(x)一般会找一个特别的素数,因此有CRC16,CRC32,有相应的标准。
发送端:有m,g,R,需要求r,然后组合成最终信息v = m*2R + r。
接收端:有v,g,计算v % g == 0则正确。
那么r怎么求呢?一般概念介绍只说用m左移R位后除以g,余数就是r。
比如输入1001,校验多项式11001,采用多项式除法
10010000
11001
------------
01011000
11001
------------
0111100
11001
------------
001110
最终发送码为1001
可是 10010000%11001 = 1110 只能说明m*2R - r能够被g整除,那为什么m*2R + r也能被g整除呢?答案在除法方式上,这里用的除法是模2除。我们可以看到CRC校验在除法过程中用的是亦或操作,
0-0=0,1-0=1,0-1=1,1-1=0;
等式挪到右边
0+0=0,1+0=1,1+1=0,0+1=1;
可以发现加法和减法的真值表完全相同,因此模2加和模2减结果相同。所以我们将被除数加上r和减去r,最终得到的余数应该相同。于是余数r可以直接接到原始信息之后,得到最终的CRC码字。
反码求和校验:
反码求和的过程更简单一些,将原始信息每16bit取反,求和,结果存在检验和字段中,接收端同样对每个16bit进行二进制反码求和,接收方在计算中包含发送方存放的检验和,最终结果应该全为1.
为何全为1?我们简化4位模拟该过程。假设发送端有1001,取反后0110,最终发送10010110,接收端收到后开始校验,取反求和
0110 + 1001=1111
结果如预期所料。其实更重要的是,当遇到进位时的处理,反码求和最高位遇到进位时,最高位进位后放到低位继续求和。意味着对于四位的求和,超过1111则循环到1,这就是反码补码的时钟循环原理,1111是4位反码求和的最大数。一个数加上自己取反得到的数正是时钟轮盘上最大那个数。接收端由于包含了发送端计算的反码和。反码和取反+反码和 = 全1.
有了对这些原理的理解,相信自己也能实现CRC校验和反码求和校验算法了。具体的代码网上一大堆,这里就不贴了,仅看了代码,只会复制,不会重写。。。
CRC、反码求和校验 原理分析的更多相关文章
- CRC校验源码分析
这两天做项目,需要用到 CRC 校验.以前没搞过这东东,以为挺简单的.结果看看别人提供的汇编源程序,居然看不懂.花了两天时间研究了一下 CRC 校验,希望我写的这点东西能够帮助和我有同样困惑的朋友节省 ...
- Handler系列之原理分析
上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...
- Java NIO使用及原理分析(1-4)(转)
转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...
- 原子类java.util.concurrent.atomic.*原理分析
原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...
- Android中Input型输入设备驱动原理分析(一)
转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...
- 转载:AbstractQueuedSynchronizer的介绍和原理分析
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- Camel运行原理分析
Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...
- NOR Flash擦写和原理分析
NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...
- 使用AsyncTask异步更新UI界面及原理分析
概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...
随机推荐
- 分布式系列文章——Paxos算法原理与推导
Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上有很多讲解Paxos算法的文章,但是质量参差不齐.看了很多关于Paxos的资 ...
- Yeoman 官网教学案例:使用 Yeoman 构建 WebApp
STEP 1:设置开发环境 与yeoman的所有交互都是通过命令行.Mac系统使用terminal.app,Linux系统使用shell,windows系统可以使用cmder/PowerShell/c ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 修改eclipse皮肤
习惯了vim黑色背景的程序猿们想必用eclipse时会倍感的不适应吧,不过没关系,因为eclipse的皮肤是可以自己定制的! 下面是我电脑上的eclipse界面,看到这个是不是找回了vim的感觉呢? ...
- Unity3D 5.3 新版AssetBundle使用方案及策略
1.概览 Unity3D 5.0版本之后的AssetBundle机制和之前的4.x版本已经发生了很大的变化,一些曾经常用的流程已经不再使用,甚至一些老的API已经被新的API所取代. 因此,本文的主要 ...
- MongoDB常用操作--集合1
1.创建集合有两种方式,显示创建和隐式创建 显示创建可以使用命令 db.createCollection("集合名称") 隐式创建可以使用命令 db.集合名称.insert({}) ...
- Linux基础介绍【第八篇】
Linux网络基础 网线 568A 568B 线序:橙白橙 绿白蓝 蓝白绿 棕白棕 交换机.路由器 交换机:DLINK.H3C.CISCO 交换机(Switch)是一种用于电信号转发的网络设备.它可以 ...
- Java
2016-12-17 21:10:28 吉祥物:Duke(公爵) Logo:咖啡(爪哇岛盛产咖啡) An overview of the software development proce ...
- 整体二分QAQ
POJ 2104 K-th Number 时空隧道 题意: 给出一个序列,每次查询区间第k小 分析: 整体二分入门题? 代码: #include<algorithm> #include&l ...
- 介绍一位OWin服务器新成员TinyFox
TinyFox 是一款支持OWIN标准的WEB应用的高性能的HTTP服务器,是Jexus Web Server的"姊妹篇".TinyFox本身的功能是html服务器,所有的WEB应 ...