奇偶校验,是通过计算数据流中比特位1的个数向原数据流后补充1bit的“0”或“1”,来检查数据流是否正确的方法。
奇校验(odd parity):如果字符数据位中“1”的数目为偶数,校验位为"1";如果为奇数,校验位为“0”。
偶校验(even parity):如果字符数据位中“1”的数目为偶数,校验位为“0”;如果为奇数,校验位为“1”。
因为传输数据位中,0和1出错的概率各占50%,所以对于奇偶校验算法,只有50%的概率检测到传输数据的错误。典型应用是8bit串口数据传输后的增加校验位,用于校验串口通信数据的正确性。
1、直接法
// data: 待校验数据
// return:data中1的数目为奇数,返回true,否则返回false。
bool ParityCheck(uint32_t data)
{
bool parity = false;
while (data)
{
if (data & 0x1)
{
parity = !parity;
}
data >>= 1;
}
return parity;
}
2、常规方法
// data: 待校验数据
// return:data中1的数目为奇数,返回true,否则返回false。
bool ParityCheck(uint32_t data)
{
bool parity = false;
while (data)
{
parity = !parity;
data &= data - 1;
}
return parity;
}
3、查表法
#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)
// 通过嵌套宏定义生成校验表
// 表中说明了0-255数字中包含1的个数
// 含偶数个1,取值为0,否则取值为1
const bool ParityTable[256] =
{
P6(0), P6(1), P6(1), P6(0)
}
// data: 待校验数据
// return: data中1的数目为奇数,返回true,否则返回false。
bool ParityCheck(uint32_t data)
{
// 将高位和低位的“1”通过异或操作消除
// 最终保留的1-8位奇偶性和1-32位的奇偶性相同
data ^= data >> 16;
data ^= data >> 8;
if (ParityTable[data & 0xff])
{
return true;
}
else
{
return false;
}
}