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的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...
随机推荐
- shell注释
sh里没有多行注释,只能每一行加一个#号.只能像这样: #-------------------------------------------- # 这是一个自动打ipa的脚本,基于webfrogs ...
- SQL Server 数据加密功能解析
SQL Server 数据加密功能解析 转载自: 腾云阁 https://www.qcloud.com/community/article/194 数据加密是数据库被破解.物理介质被盗.备份被窃取的最 ...
- 在.NET Core 里使用 BouncyCastle 的DES加密算法
.NET Core上面的DES等加密算法要等到1.2 才支持,我们可是急需这个算法的支持,文章<使用 JavaScriptService 在.NET Core 里实现DES加密算法>需要用 ...
- nodejs中获取时间戳、时间差
Nodejs中获取时间戳的方法有很多种,例如: new Date().getTime() Date.now() process.uptime() process.hrtime() 平时想获取一个时间戳 ...
- ASP.NET Core: You must add a reference to assembly mscorlib, version=4.0.0.0
ASP.NET Core 引用外部程序包的时候,有时会出现下面的错误: The type 'Object' is defined in an assembly that is not referenc ...
- BPM SharePoint解决方案分享
一.需求分析 SharePoint作为微软推出的协同类平台产品,为客户提供了门户.内容.文档.流程.社区.搜索.BI等一系列的解决方案,然而其流程功能由于设计理念差异,不能完全满足客户的需求,主要原因 ...
- 一切从“简”,解放IT运维人员
运维人的神技 运维既是个技术活儿也是个苦差事,而运维人员被期望有着无限的技能:主机.存储.网络.操作系统样样精通,而且还要会写SQL.shell.开发语言java..net.python等等,对业务更 ...
- linux yum命令详解
yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能够从指定的服务器自动下载RP ...
- VisualStudio 2015 开启IIS Express可以调试X64项目
现在项目开发时总有时需要在X64下开发,这样我们就需要IIS Express中调试.不要总是放在IIS中,在Attach这样好慢. 如果不设置直接调试X64的程序,我们有可能会受到以下类似的错误 ...
- FineReport如何用JDBC连接阿里云ADS数据库
在使用FineReport连接阿里云的ADS(AnalyticDB)数据库,很多时候在测试连接时就失败了.此时,该如何连接ADS数据库呢? 我们只需要手动将连接ads数据库需要使用到的jar放置到%F ...