zoukankan      html  css  js  c++  java
  • C语言位操作奇偶校验算法

         信息是以比特流的方式传输的,类似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 - 1);
    }

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

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

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

    通过嵌套宏定义,制作一张包括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 >> 16;
    v ^= v >> 8;
    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[0] ^ p[1] ^ p[2] ^ p[3]];

    原理:取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的二进制比特位,

  • 相关阅读:
    把git项目放到个人服务器上
    关于fcitx无法切换输入法的问题解决
    博客变迁通知
    (欧拉回路 并查集 别犯傻逼的错了) 7:欧拉回路 OpenJudge 数据结构与算法MOOC / 第七章 图 练习题(Excercise for chapter7 graphs)
    (并查集) HDU 1856 More is better
    (并查集 不太会) HDU 1272 小希的迷宫
    (并查集 注意别再犯傻逼的错了) HDU 1213 How Many Tables
    (最小生成树 Kruskal算法) 51nod 1212 无向图最小生成树
    (并查集) HDU 1232 畅通工程
    (最小生成树 Prim) HDU 1233 还是畅通工程
  • 原文地址:https://www.cnblogs.com/cpoint/p/3367375.html
Copyright © 2011-2022 走看看