热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

常用校验码及示例

计算机系统运行时,各个部之间要进行数据交换.为确保数据在传送过程正确无误,常使用检验码.我们常使用的检验码有三种. 分别是奇偶校验码、海明校验码和循环冗余校验码(CRC)。奇偶校验

计算机系统运行时,各个部之间要进行数据交换. 为确保数据在传送过程正确无误,常使用检验码. 我们常使用的检验码有三种.
 分别是奇偶校验码、海明校验码和循环冗余校验码(CRC)。


奇偶校验码(Parity Codes)

奇偶校验码最简单,但只能检测出奇数位出错. 如果发生偶数位错误就无法检测. 但经研究是奇数位发生错误的概率大很多. 而且奇偶校验码无法检测出哪位出错.所以属于无法矫正错误的校验码。奇偶校验码是奇校验码和偶校验码的统称.
 它们都是通过在要校验的编码上加一位校验位组成. 如果是奇校验加上校验位后,编码中1的个数为奇数个。如果是偶校验加上校验位后,编码中1的个数为偶数个。

例:原编码   奇校验 偶校验0000   0000 1 0000 00010   0010 0 0010 11100   1100 1 1100 01010   1010 1 1010 0

如果发生奇数个位传输出错,那么编码中1的个数就会发生变化. 从而校验出错误,要求从新传输数据。目前应用的奇偶校验码有3种.

水平奇偶校验码对每一个数据的编码添加校验位,使信息位与校验位处于同一行.

垂直奇偶校验码把数据分成若干组,一组数据排成一行,再加一行校验码. 针对每一行列采用奇校验 或 偶校验例: 有32位数据10100101 00110110 11001100 10101011垂直奇校验    垂直偶校验10100101    10100101    数据00110110    0011011011001100    1100110010101011    1010101100001011    11110100    校验

水平垂直奇偶校验码就是同时用水平校验和垂直校验例:奇校验 奇水平     偶校验 偶水平 10100101 1     10100101 0   数据 00110110 1     00110110 0 11001100 1     11001100 0 10101011 0     10101011 1 00001011 0     11110100 1   校验

  我们把传送过来的1100111000逐位相加就会得到一个1,应该注意的的,如果在传送中1100111000变成为0000111000,通过上面的运算也将得到1,接收方就会认为传送的数据是正确的,这个判断正确与否的过程称为校验。而使用上面方法进行的校验称为奇校验,奇校验只能判断传送数据中奇数个数据从0变为1或从1变为0的情况,对于传送中偶数个数据发生错误,它就无能为力了。
  Odd Parity(奇校验),校核数据完整性的一种方法,一个字节的8个数据位与校验位(parity bit )加起来之和有奇数个1。校验线路在收到数后,通过发生器在校验位填上0或1,以保证和是奇数个1。因此,校验位是0时,数据位中应该有奇数个1;而校验位是1时,数据位应该有偶数个1。如果读取数据时发现与此规则不符,CPU会下令重新传输数据。

  奇/偶校验(ECC)是数据传送时采用的一种校正数据错误的一种方式,分为奇校验和偶校验两种。 如果是采用奇校验,在传送每一个字节的时候另外附加一位作为校验位,当实际数据中“1”的个数为偶数的时候,这个校验位就是“1”,否则这个校验位就是“0”,这样就可以保证传送数据满足奇校验的要求。在接收方收到数据时,将按照奇校验的要求检测数据中“1”的个数,如果是奇数,表示传送正确,否则表示传送错误。 同理偶校验的过程和奇校验的过程一样,只是检测数据中“1”的个数为偶数。

海明校验码(Hamming Code)

海明码也是利用奇偶性来校验数据的. 它是一种多重奇偶校验检错系统,它通过在数据位之间插入k个校验位,来扩大码距,从而实现检错和纠错.

设原来数据有n位,要加入k位校验码.怎么确定k的大小呢? k个校验位可以有pow(2,k) (代表2的k次方) 个编码,其中有一个代表是否出错. 剩下pow(2,k)-1个编码则用来表示到底是哪一位出错. 因为n个数据位和k个校验位都可能出错,所以k满足pow(2,k)-1
 >= n+k。

设 k个校验码为 Pk,...,P1, n个数据位为D(n-1),...,D1,D0,产生的海明码为 H(n+k),...,H1。如有8个数据位,根据pow(2,k)-1 >= n+k可以知道k最小是4。那么得到的海明码是:

H12 H11 H10 H9 H8 H7 H6 H5 H4 H3 H2 H1D7 D6 D5 D4 P4 D3 D2 D1 P3 D0 P2 P1  (Pi在海明码的第pow(2,i-1)位置;数据位Di则依序从低到高占据海明码中剩下位置)

然后怎么知道Pi校验哪个位呢. 自己可以列个校验关系表

海明码 下标 校验位组H1(P1) 1 P1H2(P2) 2 P2H3(D0) 1+2 P1,P2H4(P3) 4 P3H5(D1) 1+4 P1,P3H6(D2) 2+4 P2,P3H7(D3) 1+2+4 P1,P2,P3H8(P4) 8 P4H9(D4) 1+8 P1,P4H10(D5) 2+8 P2,P4H11(D6) 1+2+8 P1,P2,P4H12(D7) 4+8 P3,P4

从表中可以看出P1校验 P1,D0,D1,D3,D4,D6P2校验 P2,D0,D2,D3,D5,D6P3校验 P3,D1,D2,D3,D7P4校验 P4,D4,D5,D6,D7其实上表很有规律很容易记,要知道海明码Hi由哪些校验组校验,可以把i化成二进制数数中哪些位k是1,就有哪些Pk校验

如H7 7=0111 所以由P1,P2,P3。 H11 11=1011 所以由P1,P2,P4。  H3 3=0011 所以由P1,P2

那看看Pi的值怎么确定,如果使用偶校验,则P1=D0 xor D1 xor D3 xor D4 xor D6P2=D0 xor D2 xor D3 xor D5 xor D6P3=D1 xor D2 xor D3 xor D7P4=D4 xor D5 xor D6 xor D7其中xor是异或运算,奇校验的话把偶校验的值取反即可.

那怎么校验错误呢. 其实也很简单. 先做下面运算.G1 = P1 xor D0 xor D1 xor D3 xor D4 xor D6G2 = P2 xor D0 xor D2 xor D3 xor D5 xor D6G3 = P3 xor D1 xor D2 xor D3 xor D7G4 = P4 xor D4 xor D5 xor D6 xor D7

若采用偶校验,则G4G3G2G1全为0表示接收到的数据无错误(奇校验则应全为1)。当G4G3G2G1不全为0说明发生了错误,而且G4G3G2G1的十进制指出了发生错误的位置,例如 G4G3G2G1=1010,说明H10(D5)出错了,将其取反即可纠正错误。

异或,英文为exclusive OR,或缩写成xor。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。a⊕b
 = (?a ∧ b) ∨ (a ∧?b)如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。


循环冗余校验码(Cyclic Redundancy Check)

CRC码利用生成多项式为k个数据位产生r个校验位进行编码,其编码长度为n=k+r所以又称 (n,k)码. CRC码广泛应用于数据通信领域和磁介质存储系统中. CRC理论非常复杂,一般书就给个例题,讲讲方法.现在简单介绍下它的原理:

在k位信息码后接r位校验码,对于一个给定的(n,k)码。可以证明(数学高手自己琢磨证明过程)存在一个最高次幂为 n-k=r 的多项式g(x),根据g(x)可以生成k位信息的校验码,g(x)被称为 生成多项式

用C(x)=C(k-1)C(k-2)...C0表示k个信息位,把C(x)左移r位,就是相当于 C(x)*pow(2,r) 给校验位空出r个位来了.给定一个 生成多项式g(x),可以求出一个校验位表达式r(x) 。C(x)*pow(2,r) / g(x) = q(x) + r(x)/g(x) 用C(x)*pow(2,r)去除生成多项式g(x)商为q(x)余数是r(x)。所以有C(x)*pow(2,r)
 = q(x)*g(x) + r(x)

C(x)*pow(2,r) + r(x)就是所求的n位CRC码,由上式可以看出它是生成多项式g(x)的倍式.所以如果用得到的n位CRC码去除g(x)如果余数是0,就证明数据正确. 否则可以根据余数知道出错位.在CRC运算过程中,四则运算采用 mod 2运算(后面介绍),即不考虑进位和借位. 所以上式等价于C(x)*pow(2,r) + r(x) = q(x)*g(x)

继续前先说下基本概念吧.1.多项式和二进制编码x的最高次幂位对应二进制数的最高位.以下各位对应多项式的各幂次. 有此幂次项为1,无为0. x的最高幂次为r时, 对应的二进制数有r+1位 例如g(x)=pow(x,4) + pow(x,3) + x + 1 对应二进制编码是 11011

2.生成多项式是发送方和接受方的一个约定,也是一个二进制数,在整个传输过程中,这个数不会变.在发送方利用 生成多项式 对信息多项式做模2运算生成校验码.在接受方利用 生成多项式 对收到的 编码多项式 做模2运算校验和纠错.

生成多项式应满足:a.生成多项式的最高位和最低位必须为1b.当信息任何一位发生错误时,被生成多项式模2运算后应该使余数不为0c.不同位发生错误时,应该使余数不同.d.对余数继续做模2除,应使余数循环.

生成多项式很复杂,不过不用我们生成。

下面给出一些常用的生成多项式表n k 二进制码(自己根据多项式和二进制编码 的介绍转)7 4 1011 或 11017 3 11011 或 1011115 11 101131 26 100101

3.模2运算a.加减法法则0 +/- 0 = 00 +/- 1 = 11 +/- 0 = 11 +/- 1 = 0注意:没有进位和借位

b.乘法法则利用模2加求部分积之和,没有进位

c.除法法则利用模2减求部分余数,没有借位,每商1位则部分余数减1位,余数最高位是1就商1,不是就商0,当部分余数的位数小于余数时,该余数就是最后余数.

例 1110
1011)1100000101111101011101010110010(每商1位则部分余数减1位,所以前两个0写出)0000010(当部分余数的位数小于余数时,该余数就是最后余数)最后商是1110余数是010

好了说了那么多没用的理论.下面讲下CRC的实际应用.例: 给定的生成多项式g(x)=1011, 用(7,4)CRC码对C(x)=1010进行编码.由题目可以知道下列的信息:C(x)=1010,n=7,k=4,r=3,g(x)=1011 C(x)*pow(2,3)=1010000 C(x)*pow(2,3) / g(x) = 1001 + 11/1011 所以r(x)=011.所以要求的编码为1010011例2: 上题中,数据传输后变为1000011,试用纠错机制纠错. 1000011 / g(x) = 1011 + 110/1011

不能整除,所以出错了. 因为余数是110.查1011出错位表可以知道是第5位出错.对其求反即可.

  冗余码的计算方法是,先将信息码后面补0,补0的个数是生成多项式最高次幂;将补零之后的信息码除以G(X),注意除法过程中所用的减法是模2减法,即没有借位的减法,也就是异或运算。当被除数逐位除完时,得到比除数少一位的余数。此余数即为冗余位,将其添加在信息位后便构成CRC码字。

  例如,假设信息码字为11100011,生成多项式G(X)=X^5+X^4+X+1,计算CRC码字。

  G(X) = X^5+X^4+X+1,也就是110011,因为最高次是5,所以,在信息码字后补5个0,变为1110001100000。用1110001100000除以110011,余数为11010,即为所求的冗余位。

  因此发送出去的CRC码字为原始码字11100011末尾加上冗余位11010,即 1110001111010。接收端收到码字后,采用同样的方法验证,即将收到的码字除以G(X),发现余数是0,则认为码字在传输过程中没有出错。

---------------------

本文来自 ncepu_xu 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/ncepu_xu/article/details/70208630?utm_source=copy

常用校验码及示例


推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
author-avatar
没有完美的谎言
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有