linux源码奇偶校验方法

求8位奇偶校验
Linux函数方法:

1
static inline int parity8(u8 val)

常用方法

一、循环遍历

1
2
3
4
5
6
7
8
while(val)
{
if (val& 0x1)
{
parity = !parity;
}
data >>= 1;
}

二、异或操作

回忆一下,相异为1,相同为0。

看,如果我们只针对2个bit,是不是可以对异或操作的定义换一个说法,偶数个1为0,奇数个1为1,所以针对2个bit来说,异或操作就是求奇偶校验。

举个例子。

0B00,偶数个1,两比特相异为0.

0B01,0B10,奇数个1,两比特相异为1.

0B11,偶数个1,两比特相异为0.

就8bit而言。

我们只需要像下面这样,即每次折叠一下,上下2个bit对齐求异或。

1
2
3
val ^= val >> 4;
val ^= val >> 2;
val ^= val >> 1;

我们通过位运算实现了类似并行的操作。

三、Linux函数方法

函数原型:

1
2
3
4
5
6
7
8
9
static inline int parity8(u8 val)
{
/*
* One explanation of this algorithm:
* https://funloop.org/codex/problem/parity/README.html
*/
val ^= val >> 4;
return (0x6996 >> (val & 0xf)) & 1;
}

嗯?0x6996是个啥?嗯,看懂了很简单也很惊艳

val在经过一次折叠异或之后,其取值是0-15。

然后奇偶校验的返回值不是0就是1。所以如果这个时候我们查表只需要2个字节即可。

嗯,是的,0x6996即是0B0110100110010110。

它的对应位置的bit,正好是0-15对应的奇偶返回值,所以我们直接移位查表即可。

压缩到极致的位表


相关链接(侵删)

  1. Linux源码中的位运算技巧之计算奇偶校验

=================我是分割线=================

欢迎到公众号来唠嗑: