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的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...
随机推荐
- 理解Maven中的SNAPSHOT版本和正式版本
Maven中建立的依赖管理方式基本已成为Java语言依赖管理的事实标准,Maven的替代者Gradle也基本沿用了Maven的依赖管理机制.在Maven依赖管理中,唯一标识一个依赖项是由该依赖项的三个 ...
- ES6模块import细节
写在前面,目前浏览器对ES6的import支持还不是很好,需要用bable转译. ES6引入外部模块分两种情况: 1.导入外部的变量或函数等: import {firstName, lastName, ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
- MVC Core 网站开发(Ninesky) 2、栏目
栏目是网站的常用功能,按照惯例栏目分常规栏目,单页栏目,链接栏目三种类型,这次主要做添加栏目控制器和栏目模型两个内容,控制器这里会用到特性路由,模型放入业务逻辑层中(网站计划分数据访问.业务逻辑和We ...
- Smarty的基本使用与总结
含义: Smarty是PHP的一个引擎模板,可以更好的进行逻辑与显示的分离,即我们常说的MVC,这个引擎的作用就是将C分离出来. 环境需求:PHP5.2或者更高版本 我使用的环境是:PHP5.3,wi ...
- mysql进阶之存储过程
往往看别人的代码会有这样的感慨: 看不懂 理还乱 是离愁 别是一番滋味在心头 为什么要使用存储过程? 在mysql开发中使用存储过程的理由: 当希望在不同的应用程序或平台上执行相同的函数,或者封装特定 ...
- JDBC MySQL 多表关联查询查询
public static void main(String[] args) throws Exception{ Class.forName("com.mysql.jdbc.Driver&q ...
- html中返回上一页的各种写法【转】
超链接返回上一页代码: <a href="#" onClick="javascript :history.back(-1);">返回上一页</ ...
- document.compatMode
在我电脑屏幕上显示的 电脑是 1920*1080这是在document.compatMode:css1Compat模式 window.screen.availWidth 1920 window.scr ...
- Kotlin的android扩展:对findViewById说再见(KAD 04)
作者:Antonio Leiva 时间:Dec 12, 2016 原文链接:http://antonioleiva.com/kotlin-android-extensions/ 你也许已厌倦日复一日使 ...