奇偶校验原理,三种方式实现

奇偶校验位介绍

奇偶校验位是一种用于检测和纠正数据传输中出现的错误的机制。在数据传输过程中,数据被分割为固定大小的块,一般为一字节(8 位)。每个字节都会附加上一个奇偶校验位,用于表示该字节中 1 的个数是奇数还是偶数。

在奇偶校验位中,如果数据字节中 1 的个数是奇数,则校验位被设置为 1;如果是偶数,则校验位被设置为 0。

在接收端,当接收到数据时,会重新计算接收到的字节中 1 的个数,并与接收到的校验位进行比较。如果两者不匹配,则表示此数据在传输过程中出现了错误。

奇偶校验位只能检测错误,没有纠正错误的能力。在简单的通信环境中,如串口通信,奇偶校验位可以提供一定程度的错误检测功能。

奇偶检测示例代码

  1. 判断最低位是否为 1,然后左移一位;
  2. 如此循环,直至 data 为 0。
c 复制代码
// 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;
}

另一种实现,通过 data&(data-1) 计算 1 的个数。

c 复制代码
// data: 待校验数据
// return:data中1的数目为奇数,返回true,否则返回false。
bool ParityCheck(uint32_t data)
{
    bool parity = false;
    while (data)
    {
        parity = !parity;
        data &= data - 1;
    }
    return parity;
}

采用校验表实现,校验表表明了[0, 255]范围中数字包含 1 的个数,即偶数个 1,为 0,否则为 1。

c++ 复制代码
#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;
    }
}

总结

采用奇偶校验位实现的简易检测过程如下:

  1. 数据被分割为固定大小的块,通常是 8 位(一个字节)。
  2. 对每个数据块计算其二进制中 1 的个数,如果为奇数,则设置校验位为 0,如果为偶数,则设置校验位为 1。
  3. 将数据块和校验位一起传输给接收方。
  4. 接收方在接收数据块后,重新计算数据块中 1 的个数。
  5. 接收方使用重新计算的结果与接收到的校验位进行比较。
  6. 如果重新计算的结果与接收到的校验位相等,则数据块没有错误。
  7. 如果重新计算的结果与接收到的校验位不相等,则说明数据块中发生了错误。

奇偶校验能够检测到单个位的错误,但无法纠正错误,只能检测错误的存在。如果出现错误,通常需要重新传输或采取其他纠错措施。

相关推荐
Code哈哈笑25 分钟前
【基于Spring Boot 的图书购买系统】深度讲解 用户注册的前后端交互,Mapper操作MySQL数据库进行用户持久化
数据库·spring boot·后端·mysql·mybatis·交互
Javatutouhouduan41 分钟前
线上问题排查:JVM OOM问题如何排查和解决
java·jvm·数据库·后端·程序员·架构师·oom
多多*1 小时前
Spring之Bean的初始化 Bean的生命周期 全站式解析
java·开发语言·前端·数据库·后端·spring·servlet
Villiam_AY2 小时前
Go 后端中双 token 的实现模板
开发语言·后端·golang
拾贰_C6 小时前
【SpringBoot】MyBatisPlus(MP | 分页查询操作
java·spring boot·后端·spring·maven·apache·intellij-idea
就叫飞六吧11 小时前
Spring Security 集成指南:避免 CORS 跨域问题
java·后端·spring
冼紫菜12 小时前
[特殊字符]CentOS 7.6 安装 JDK 11(适配国内服务器环境)
java·linux·服务器·后端·centos
秋野酱14 小时前
Spring Boot 项目的计算机专业论文参考文献
java·spring boot·后端
香饽饽~、14 小时前
【第二篇】 初步解析Spring Boot
java·spring boot·后端