奇偶校验算法

1即计算出所给数中包含1的个数

方法一:每一位分别异或(时间复杂度O(n)n代表数位数)

函数功能:如果1的个数为奇数个,则返回1,如果1的个数为偶数个,则返回0。

parity_check(unsigned x)

{

int val=0;

while(x)

{

val^=x;//val 和x进行异或运算

x>>=1;//x右移一位

}

return val&0x1;//取末位运算. val的二进制形式最后一位位1则返回1,为0则返回0.

}

实例分析,假设无符号数x转换成二进制后长度为5位,五个位置的数据(二进制数,0或者1)分别记为①②③④⑤,两个位置的数进行异或运算记为①^②。注意,给定x后化成二进制形式最高位①为1。

则整个程序执行过程(只需要考虑异或运算结果的末位数)可以表述为:

(((⑤^④)^③)^②)^①——表达式1

假设⑤和④不同,则⑤^④运算结果为1,表示有一个1。表达式1可以化成:((1^③)^②)^①——表达式2

③如果不是1,则表示⑤④③中只有一个1;如果是1,⑤④③中有两个1.这两种结果等价于1^③运算的结果。假设③就是1,则表达式2可以化成:(0^②)^①——表达式3

假设②为0(①为1是前提),则表达式3可以化简为:(0^0)^1,运算结果为1,即五个二进制数中有奇数个1,⑤和④中有一个1,③是1,②为0,①为1共3个1得以验证。

该算法形式简单,功能强大,却不好理解。该函数可用于奇偶校验。

方法二:时间复杂度0(1的个数)

int a=1;

while(x)

{

a^=0;//改为 count++;可以计算该数二进制中包含1的个数

x&(x-1);

}

方法三:时间复杂度0(lgn)n为位数

8位的数据D(D7~D0),他的算法为:

D ^= D >>4;

D ^= D >>2;

D ^= D >>1;

D&=1;

最后D就是偶校验的值了。

可能有的同学一时之间看不明白算法的原理,这里解释一下吧。

首先从D里面找两个位D1和D0,而D1D0的偶校验值E0=D1^D0,这个大家都明白的,然后D3和D2的检验值E1=D3^D2,同理还有E2=D5^D4以及E3=D7^D6;

E0=1时代表了D1和D0里面有奇数个1,E1、E2和E3同理;

然后复习一下小学数学:奇数*奇数=奇数,偶数*奇数=偶数

如果E0和E1里面有奇数个1,那么D3~D0里面就有奇数数个1,此时D3~D0的偶校验值为1;

“如果E0和E1里面有奇数个1”这句话的意思不就是求由E1和E0组成的两位二进制的偶校验么?而且当E1E0的偶校验值F0=1时,对应的D3~D0的偶校验值也为1。

同理,E3E2的偶校验值F1=1时,对应的D7~D4的偶校验值也为1;

继续同理,由F1和F0组成的两位二进制的偶校验G0=1时,对应的是E3~E0的偶校验值为1,同时对应的D7~D0的偶校验值为1。

于是求D7~D0的偶校验值变成了求F1F0的偶校验值。

那么首先就要将D7~D0的8个位两两分组后在分别求异或,然后再将得出的值的4个位两两分组后分别异或,最后将得出的值的2个位进行异或,得到的值就是D7~D0的偶校验值了。

而分组则不必是相邻的,将D右移4位再和原来的D进行异或的话就简单多了

D7——D3

D6——D2

D5——D1

D4——D0

如此类推,每次先进行右移,然后和原来的值异或,最终就能得到D的校验值了;另外在计算的过程中,仅仅需要关注后面的位数就可以了,如第二次计算时,高4位会有一些数据,到最后高7位也会有数据的,但这些数据都已经没有用了,所以最后只需要来一个&1就可以l。

于是文章开头的那段8位二进制数的算法为:

D ^= D >>4;

D ^= D >>2;

D ^= D >>1;

D&=1;

另外对于2^N位二进制数,第一次右移(2^N)/2位后再异或,然后重复类似的计算N次就可以了。

时间: 2024-12-09 09:50:43

奇偶校验算法的相关文章

谈谈异或加密

0. 前言 本文包括如下几个内容: 异或算法 异或加密 两个整数交换问题 1. 异或算法 异或是数字逻辑中的基本概念,也是每种编程语言都支持的基本运算.基本原理就是,对于数字1和0有如下的运算公式: 1 ^ 1 = 0 0 ^ 0 = 0 1 ^ 0 = 1 0 ^ 1 = 1 很自然地,这个运算可以扩展到一长串码流上. 更常见的是字节一级或整数的异或运算,可以参考相应的编程语言的相关介绍. 2. 异或加密 异或加密是最简单的一种加密方法,简单来讲,假定有一串码流A,然后可以用key进行加密,把

Hyper-V Server存储介绍

主机服务器架构利用的存储设计对主机和来宾的性能有着极大的影响.存储性能是驱动器.接口.控制器.缓存.协议.SAN.HBA.驱动程序和操作系统考虑事项的复杂混合体.通常,存储架构的整体性能是通过最大吞吐量.每秒最大 IO 操作数 (IOPS) 和延迟或响应时间来测量的.尽管这三个因素均非常重要,但 IOPS 和延迟与服务器虚拟化的关系最为密切. 存储连接:Hyper-V主机服务器可通过三种不同的方式访问独立磁盘和存储阵列:直接连接存储.iSCSI 存储区域网络和光纤通道存储区域网络. 1) 直接连

Ceph源码解析:CRUSH算法

1.简介 随着大规模分布式存储系统(PB级的数据和成百上千台存储设备)的出现.这些系统必须平衡的分布数据和负载(提高资源利用率),最大化系统的性能,并要处理系统的扩展和硬件失效.ceph设计了CRUSH(一个可扩展的伪随机数据分布算法),用在分布式对象存储系统上,可以有效映射数据对象到存储设备上(不需要中心设备).因为大型系统的结构式动态变化的,CRUSH能够处理存储设备的添加和移除,并最小化由于存储设备的的添加和移动而导致的数据迁移. 为了保证负载均衡,保证新旧数据混合在一起.但是简单HASH

栈式自编码算法

学习UFDL栈式自编码算法的笔记 深度网络的优势 深度神经网络,即含有多个隐藏层的神经网络.通过引入深度网络,我们可以计算更多复杂的输入特征.因为每一个隐藏层可以对上一层的输出进行非线性变换,因此深度神经网络拥有比"浅层"网络更加优异的表达能力(例如可以学到更加复杂的函数关系). 其实三层网络,只要能无限增加隐层的单元数就能拟合任何函数.而使用深度网络的最主要优势是:它能以更加紧凑简洁的方式来表达比浅层网络大得多的函数集合.正式点说,我们可以找到一些函数,这些函数可以用k层网络简洁地表

双重编解码算法对比

概述 双重编解码算法是实现数据保护的关键技术.磁盘阵列中的常用算法是RAID6,其属于Reed-solomon算法范畴.RAID6算法计算复杂度较高,往往需要硬件加速单元的支持.随着闪存技术的发展,新的编解码技术层出不穷,因此有必要了解常用阵列技术的双重编解码算法,通常来讲,常用双重编解码算法主要有如下三种: 1,二维(2D)奇偶校验方法 2,EVEN-ODD编码校验法 3,Reed-Solomon编码校验法 下面会对这三种算法的原理进行详细说明,然后对比这三种算法的性能及计算复杂度. 二维奇偶

传输数据校验算法研究

 今天简单介绍一些传输数据校验的方法,就昨天整理的资料和就我的理解写的Demo做个总结!希望大家多多指教! 定义 通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的一个校验值.接收方用同样的算法计算一次校验值,如果和随数据提供的校验值一样,说明数据是完整的. 实际应用 防止自己的程序被篡改. 有些可执行程序,当被改了资源时再运行会有文件已损坏的提示,这就是使用了数据校验.本例是用md5做为数据校验的算法.当然你可以使用个性化的 比如des作为数字签名,那样安全性更高. 校验方法

校验算法专辑

由于最近一直在接触公司的通讯协议,包括基于HTTP协议.SOCKET.串口通讯协议封装的PUSH.PULL通信协议SDK. 通讯协议无可避免的需要校验,想想以前在B公司自己定制的通讯协议连校验的算法都木有,简直low到不行,如此,问题来了, 主流的通讯协议校验算法都有哪些? 于是这篇文章就应运而生了: 首先,比较常用的算法有: 一.奇偶校验: 1. 定义 根据被传输的一组二进制代码中"1"的个数是奇数或偶数来进行校验. 使用:通常专门设置一个奇偶校验位,存放代码中"1&quo

写给嵌入式程序员的循环冗余校验(CRC)算法入门引导

写给嵌入式程序员的循环冗余校验(CRC)算法入门引导 http://blog.csdn.net/liyuanbhu/article/details/7882789 前言 CRC校验(循环冗余校验)是数据通讯中最常采用的校验方式.在嵌入式软件开发中,经常要用到CRC 算法对各种数据进行校验.因此,掌握基本的CRC算法应是嵌入式程序员的基本技能.可是,我认识的嵌入式程序员中能真正掌握CRC算法的人却很少,平常在项目中见到的CRC的代码多数都是那种效率非常低下的实现方式. 其实,在网上有一篇介绍CRC

【转】循环冗余校验(CRC)算法入门引导

原文地址:循环冗余校验(CRC)算法入门引导 参考地址:https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks#References  给出了CRC 计算的详细信息.想要深入学习,可以从这个网址开始.尤其是最后给出的 Reference 各个是精品 http://www.zorc.breitbandkatze.de/crc.html 是个非常有用的网站,文中给出的代码都与那里的结果进行了对比 写给嵌入式程序员的循