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的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...
随机推荐
- tLinux 2.2下安装Mono 4.8
Tlinux2.2发行版基于CentOS 7.2.1511研发而成,内核版本与Tlinux2.0发行版保持完全一致,更加稳定,并保持对Tlinux2.0的完全兼容.Mono 4版本要求CentOS 7 ...
- Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境
首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...
- console的高级使用
1.console.table()用来表格化展示数据. var people = { zqz: { name: 'zhaoqize', age: 'guess?' }, wdx: { name: 'w ...
- C++中的命名空间
一,命名空间(namespace)的基本概念以及由来 1.什么是标识符: 在C++中,标识符可以是基本的变量,类,对象,结构体,函数,枚举,宏等. 2.什么是命名空间: 所谓的命名空间是指标识符的可见 ...
- Servlet监听器笔记总结
监听器Listener的概念 监听器的概念很好理解,顾名思义,就是监视目标动作或状态的变化,目标一旦状态发生变化或者有动作,则立马做出反应. Servlet中的也有实现监听器的机制,就是Listene ...
- git-2.10.2-64-bit介绍&&git下载&&git安装教程
Git介绍 分布式:Git系统是一个分布式的系统,是用来保存工程源代码历史状态的命令行工具. 保存点:Git的保存点可以追踪源码中的文件, 并能得到某一个时间点上的整个工程项目的状态:可以在该保存点将 ...
- Asp.Net Core + Dapper + Repository 模式 + TDD 学习笔记
0x00 前言 之前一直使用的是 EF ,做了一个简单的小项目后发现 EF 的表现并不是很好,就比如联表查询,因为现在的 EF Core 也没有啥好用的分析工具,所以也不知道该怎么写 Linq 生成出 ...
- 防线修建 bzoj 2300
防线修建(1s 512MB)defense [问题描述] 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上层现在还 ...
- autocomplete的使用
autocomplete使用分为本地调用方法和读取远程读取数据源的方法 (1)本地调用方法 <script src="Scripts/jquery-1.4.1.min.js" ...
- css样式之border-radius
border-radius 属性设置边框的园角 可能的值:像素,百分比 扩展延伸 html代码 <div></div> css代码 div { height: 200px; w ...