信息是以比特流的方式传输的,类似01000001。在传输过程中,有可能会发生错误,比如,我们存储了01000001,但是取出来却是01000000,即低位由0变成了1。为了检测到这种错误,我们可以通过“奇偶校验”来实现。假如,我们存储的数据是一个字节,8个比特位,那我们就可以计算每个字节比特位是1的个数,如果是偶数个1,那么,我们就把第九个位设为1,如果是奇数个1,那么就把第九个位设为0,这样连续9个字节比特位为1的位数肯定是奇数。这中方法叫做“奇校验”,“偶校验”和此类似。当然,在实际应用中,也可以把一个字节的前7位作为数据位,最后一个为作为校验位。

1、奇偶校验的常规方法:

unsigned int v;       // 待检测的数字
bool parity = false; //初始判断标记
while (v)
{
parity = !parity;
v = v & (v - );
}

通过while循环,每执行一次,v中1的数目就会减少1,如果v中1的数目为奇数,则parity=true,否则parity=false。

2、通过构建字典表进行奇偶校验:

static const bool ParityTable256[] =
{
# define P2(n) n, n^, n^, n
# define P4(n) P2(n), P2(n^), P2(n^), P2(n)
# define P6(n) P4(n), P4(n^), P4(n^), P4(n)
P6(), P6(), P6(), P6()
};

通过嵌套宏定义,制作一张包括0~255各个数字中包含1的个数,其中包含偶数个1,则ParityTable256[i]=0,否则ParityTable256[i]=1;

如果要判定char类型的b中i的个数的奇偶,可以直接使用下面的代码:

unsigned char b;
bool parity = ParityTable256[b];

而对于32-bit的数,则使用下面的代码:

unsigned int v;
v ^= v >> ;
v ^= v >> ;
bool parity = ParityTable256[v & 0xff];

原理:

(1)通过v^=v>>16,将v中的低16位与高16位进行按位或(^)操作, 相当于0~16位保留1的总个数的奇偶与v中的1的总  个数的奇偶相同;

(2)通过v^=v>>8,将v中的9~16位与0~8位进行按位或(^)操作,相当于0~8位保留1的总个数的奇偶与0~16中1的总个数的奇偶相同;

(3)通过(1)(2)操作,最初v中1的总个数的奇偶与最后v中1~8位中1的总个数的奇偶相同,v&0xff相当于获取v中1~8比特位的1,然后再查表即可。

或者使用如下的代码:

unsigned char * p = (unsigned char *) &v;
parity = ParityTable256[p[] ^ p[] ^ p[] ^ p[]];

原理:取v的地址,并进行强制类型转换为char*,

e.g. v=1234

二进制表示为:

00000000 00000000 00000100 11010010

p[0]:11010010

p[1]:00000100

p[2]:00000000

p[3]:00000000

^------------

11010110

通过p[0] ^ p[1] ^ p[2] ^ p[3]] 操作,将p[i]中的所有的1都放在一个8位的数中,然后查表即可

3、使用64位乘法与模除法进行奇偶校验

unsigned char b;
bool parity =
(((b * 0x0101010101010101

原理:
0x0101010101010101ULL://0000 0001 0000 0001 0000 0001 0000 0001 0000 0001 0000 0001 0000 0001 0000 0001

0x8040201008040201ULL://1000 0000 0100 0000 0010 0000 0001 0000 0000 1000 0000 0100 0000 0010 0000 0001

0x1FF :  //0001 1111 1111

b * 0x0101010101010101ULL  将1~8位设置为b的二进制比特位,

C语言位操作--奇偶校验算法的更多相关文章

  1. C语言位操作的算法

    1.头文件 #ifndef _INC_BITOPERATION #define _INC_BITOPERATION #endif /* 封装了所有的位操作运算 */ #include<stdio ...

  2. 0.数据结构(python语言) 基本概念 算法的代价及度量!!!

    先看思维导图: *思维导图有点简陋,本着循循渐进的思想,这小节的知识大多只做了解即可. *重点在于算法的代价及度量!!!查找资料务必弄清楚. 零.四个基本概念 问题:一个具体的需求 问题实例:针对问题 ...

  3. 10个经典的C语言面试基础算法及代码

    10个经典的C语言面试基础算法及代码作者:码农网 – 小峰 原文地址:http://www.codeceo.com/article/10-c-interview-algorithm.html 算法是一 ...

  4. C语言 位操作

    c语言位操作中需要注意有: 位操作只针对整型和字符型数据 在右移操作中:对无符号数和有符号中的正数补 0:符号数中的负数,取决于所使用的系统:补 0 的称为“逻辑右移”,补 1 的称为“算术右移”. ...

  5. 数据结构C语言版 弗洛伊德算法实现

    /* 数据结构C语言版 弗洛伊德算法  P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...

  6. C语言版数据结构算法

    C语言版数据结构算法 C语言数据结构具体算法 https://pan.baidu.com/s/19oLoEVqV1I4UxW7D7SlwnQ C语言数据结构演示软件 https://pan.baidu ...

  7. 用scheme语言实现SPFA算法(单源最短路)

    最近自己陷入了很长时间的学习和思考之中,突然发现好久没有更新博文了,于是便想更新一篇. 这篇文章是我之前程序设计语言课作业中一段代码,用scheme语言实现单源最段路算法.当时的我,花了一整天时间,学 ...

  8. C语言之广度优先算法

    广度优先算法又称宽度优先搜索,是一种简便的图的搜索算法之一.搜索方式大致是这样的: 直到搜索到目标结点(结点就是那些圆球球,其中有一个或者多个是目标结点)或者搜完了整个图都没找到目标结点就停止搜索. ...

  9. C语言qsort函数算法性能测试

    对于该算法的复杂性.一个直接的方法是测量的一定量的算法级数据的执行时间的感知. 随着C语言提供qsort对于示例.随着100一万次的数据,以测试其计算量.感知O(nlg(n))时间成本: C码如下面: ...

随机推荐

  1. Oracle 10.2.0.1 精简客户端配置

    装完Ooracle 11g之后客户端sqlplus复制粘贴的时候不太简单,就 用了实验室的老版本10g客户端. 前提服务端装好了,想换一个客户端.11g sql plus也能用. 文件链接: 链接:h ...

  2. maven pom文件详解

    http://www.blogjava.net/hellxoul/archive/2013/05/16/399345.html http://blog.csdn.net/houpengfei111/a ...

  3. Lua之转义字符

    print("\a");    --bell 硬件滴一声 print("a"); print("\b");    --back space  ...

  4. zabbix-agents客户端安装

    Windows下zabbix客户端的安装 记得关windows上的防火墙 1.首先需要下载zabbix_agents.rar文件 点击这里进行下载 当然也可以在www.zabbix.com进行下载 2 ...

  5. linux中sudo如何读取标准输入作为密码,避免每次都输入密码?

    需求描述: 今天想要在生产环境中,弄自动部署的脚本,但是现在呢,需要sudo权限,每次都要输入.就想看sudo如何能从标准输入读取密码. 操作过程: 1.原来的方法 [deployer@testvm ...

  6. mysql中显示当前数据库下的所有表,包括视图。

    环境说明: mysql版本:5.5.57-log 操作系统:Red Hat Enterprise Linux Server release 6.6 (Santiago) 需求:查看当前数据库下所有的表 ...

  7. wcf中的使用全双工通信(转)

    wcf中的使用全双工通信   wcf中的契约通信默认是请求恢复的方式,当客户端发出请求后,一直到服务端回复时,才可以继续执行下面的代码. 除了使用请求应答方式的通信外,还可以使用全双工.下面给出例子: ...

  8. eclipse下编译cocos2dx 3.0

    先给自己科普一下, android sdk 是给java开发者用的,  咱C++开发者用的是android ndk, 所以就是使用ndk来编译cocos2dx程序了 使用命令行创建一个项目, 我这里创 ...

  9. iOS in-app purchase详解

    in-app purchase教程: http://www.appcoda.com/in-app-purchase-tutorial/ 3.后台服务器验证收据的正确性 IOS 内支付有两种模式: 1) ...

  10. str.split()与re.split()的区别

    str.split(): >>>'hello, world'.split() >>>['hello,','world'] >>>'hello, w ...