信息是以比特流的方式传输的,类似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的二进制比特位,

最新文章

  1. 【代码笔记】iOS-用户发布后能保存崩溃
  2. 怎么使用Delphi获取当前的时间,精确到毫秒
  3. php 月初,月末时间大统计
  4. September 3rd 2016 Week 36th Saturday
  5. C#实现AES加解密方法
  6. acdream 小晴天老师系列——苹果大丰收(DP)
  7. html表格 第五节
  8. 临时笔记:flume+ CDH 的 twitter实例
  9. Jquery基础之事件操作
  10. pycharm 记录
  11. 【原创】大数据基础之Hive(2)Hive SQL执行过程之SQL解析过程
  12. 这一年多来,阿里Blink测试体系如何从0走向成熟?
  13. 汇编语言--微机CPU的指令系统(五)(移位操作指令)
  14. Vue2+VueRouter2+webpack 构建项目实战(一):准备工作
  15. 开源的服务发现项目Zookeeper,Doozer,Etcd - 木精灵的技术博客 - CSDN博客
  16. ubuntu 安装 oracle-xe-universal
  17. 记github上搭建独立域名的免费博客的方法过程
  18. Python_selenium二次封装selenium的几个方法
  19. Java执行CMD命令
  20. 测试用例和BUG描述规范

热门文章

  1. FuzzyAutocomplete代码模糊匹配智能提示
  2. SharePoint 使用ECMAscript对象模型来操作Goup与User
  3. 使用intellij idea打包并部署到外部的tomcat
  4. Batch Normalization 学习笔记
  5. Laravel查询构造器简介
  6. Java把数字格式化为货币字符串
  7. [转]spring 官方下载地址(Spring Framework 3.2.x&Spring Framework 4.0.x)
  8. jekins构建通知邮件配置及邮件附件设置,jenkins构建通知邮件没有RF的log和report文件
  9. ASP.NET MVC4优化
  10. mybatis 之 parameterType="java.util.HashMap">