海明纠错码工作原理

海明纠错码

海明码(Hamming Code)是一个可以有多个校验位,具有检测并纠正一位错误代码的纠错码,所以它也仅用于信道特性比较好的环境中,如以太局域网中,因为如果信道特性不好的情况下,出现的错误通常不是一位。

海明码的检错、纠错基本思想是将有效信息按某种规律分成若干组,每组安排一个校验位进行奇偶性测试,然后产生多位检测信息,并从中得出具体的出错位置,最后通过对错误位取反(也是原来是1就变成0,原来是0就变成1)来将其纠正。

要采用海明码纠错,需要按以下步骤来进行:

  1. 计算校验位数
  2. 确定校验码位置
  3. 确定校验码
  4. 实现校验和纠错

摘自 茶乡浪子

1. 计算校验位数

要使用海明码纠错,首先就要确定发送的数据所需要要的校验码(也就是“海明码”)位数(也称“校验码长度”)。它是这样的规定的:假设用N表示添加了校验码位后整个信息的二进制位数,用K代表其中有效信息位数,r表示添加的校验码位,它们之间的关系应满足:

N=K+r≤2r-1N=K+r \le 2^r-1N=Kr2r1

如K=5,则要求2r−r≥5+1=62^r-r≥5+1=62rr5+1=6,根据计算可以得知r的最小值为4,也就是要校验5位信息码,则要插入4位校验码。如果信息码是8位,则要求2r−r≥8+1=92^r-r \ge 8+1=92rr8+1=9,根据计算可以得知r的最小值也为4。

信息码位数与校验码位数之间的关系

信息码位数12~45~1112~2627~5758~120121~247
校验码位数2345678

2.确定校验码位置

上一步我们确定了对应信息中要插入的校验码位数,但这还不够,因为这些校验码不是直接附加在信息码的前面、后面或中间的,而是分开插入到不同的位置。但不用担心,校验码的位置很容易确定的,那就是校验码必须是在 2n2^n2n 次方位置,如第1、2、4、8、16、32,……位(对应20、21、22、23、24、25,……,是从最左边的位数起的),这样一来就知道了信息码的分布位置,也就是非 2n2^n2n 次方位置,如第3、5、6、7、9、10、11、12、13,……位(是从最左边的位数起的)。

举一个例子,假设现有一个8位信息码,即b1、b2、b3、b4、b5、b6、b7、b8,它需要插入4位校验码,即p1、p2、p3、p4,也就是整个经过编码后的数据码(称之为“码字”)共有12位。根据以上介绍的校验码位置分布规则可以得出,这12位编码后的数据就是p1、p2、b1、p3、b2、b3、b4、p4、b5、b6、b7、b8。

现假设原来的8位信息码为10011101,因现在还没有求出各位校验码值,现在这些校验码位都用“?”表示,最终的码字为:??10011101

3. 确定校验码

这些校验码的值不是随意的,每个校验位的值代表了代码字中部分数据位的奇偶性(最终要根据是采用奇校验,还是偶校验来确定),其所在位置决定了要校验的比特位序列。总的原则是:第i位校验码从当前位开始,每次连续校验2n−12^{n-1}2n1位后再跳过i位,然后再连续校验2n−12^{n-1}2n1位,再跳过2n−12^{n-1}2n1位,以此类推。最后根据所采用的是奇校验,还是偶校验即可得出第nnn位校验码的值。如下表示意:原文

数据位位置1234567891011121314151617181920...
编码后数据位置p1p2d1p4d2d3d4p8d5d6d7d8d9d10d11p16d12d13d14d15
奇偶校验位
覆盖率
p1XXXXXXXXXX
p2XXXXXXXXXX
p4XXXXXXXXX
p8XXXXXXXX
p16XXXXX

3.1 计算方法1

对每组数字位通过奇偶校验的方式来依次确定校验位的值。比如使用偶校验,校验位的值使用每组中1的个数为偶数,对组内已有数字进行异或运算得到校验位的值

3.1 计算方法2

对11000010进行汉明编码,求编码后的码字。

  1. 列出表格,从左往右(或从右往左)填入数字,但2的次方的位置不填。

    位置1234567891011121314
    数据11000010
  2. 把数据行有1的列的位置写为二进制。

    位置1234567891011121314
    数据11000010
    二进制001101011011
  3. 收集所有二进制数字,求异或。0011⊕0101⊕1011=11010011\oplus 0101 \oplus 1011=1101001101011011=1101

  4. 把1101依次填入表格中2的次方的位置(低位在左)。

    位置1234567891011121314
    数据11000010
    二进制001101011011
    校验1011
  5. 所以编码后的码字是101110010010。

4. 校验与纠错

把以上这些校验码所校验的位分成对应的组,则在接收端的对各校验位再进行逻辑“异或运算”,如果采用的是偶校验,正常情况下均为0。

如果最终发现只是一个校验组中的校验结果不符,则直接可以知道是对应校验组中的校验码在传输过程中出现了差错,因为所有校验码所在的位是只由对应的校验码进行校验;如果发现多组校验结果不正确,则查看这些组中公共校验的数据位(只有数据位才可能被几个校验码进行校验),以最终确定是哪个数据位出了差错(海明码只能检查一位出错);最后,对所找到的出错数据位取反即可实现纠错。

如计算出的每组的校验结果为p1、p2、p3、p4,均为0则正确,有一个不为0的则出错的位置在p1+10∗p2+100∗p3+1000∗p4p1+10*p2+100*p3+1000*p4p1+10p2+100p3+1000p4的位置处

5. 简单的算法实现

#include <iostream>using namespace std;namespace Encode
{// 参考 https://zh.wikipedia.org/wiki/%E6%B1%89%E6%98%8E%E7%A0%81/*** @brief encode a [5-11]-bit int to hamming code* @param inCode IN as orginal code* @param inLen IN as the length infomation* @param outCode OUT as the encoded int* @param outLen OUT as the length * @return none*/bool Hamming26(int const inCode, int const inLen, int& outCode, int& outLen){if (inLen <= 5 || inLen >= 11){return false;}int checkNum = 4;   // 校验码位outLen = checkNum + inLen;const int dataBitLoc[] = { 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14 };const int checkBitLoc[] = { 0, 1, 3, 7 };int checkSum = 0;for (int i = 0; i < inLen; ++i){int dataBit = ((inCode >> i) & 0x1);if (dataBit){outCode |=  (dataBit << dataBitLoc[i]);checkSum ^= (dataBitLoc[i] + 1);}}cout << checkSum << endl;for (int i = 0; i < checkNum; ++i){outCode |= (((checkSum >> i) & 0x1) << checkBitLoc[i]);}return true;}// 参考http://www.cnblogs.com/scrutable/p/6052127.html/*** @brief check the correctness of a hamming code* @param code received code* @param length the length of the code* @return return -1 if no error, or return the position of the error bit*/bool CheckCode(int code, int length, int& errLoc){if (length <= 9 || length >= 15){return false;}errLoc = 0;int step[4] = { 1, 2, 4, 8 };for (int i = 0; i < 4; ++i){int stepNum = 0;int checkCode = 0;for (int j = step[i] - 1; j < length;){checkCode ^= ((code >> j) & 0x1);++stepNum;if (stepNum % step[i] == 0){j += (step[i] + 1);}else {++j;}}errLoc |= ((checkCode&0x1) << i);}return true;}
}int main()
{int code = 157;int length = 8;int result, reLen;Encode::Hamming26(code, length, result, reLen);cout << "The orignal code " << code << "[" << length << "] ";// display from LSB to MSBfor (int i = 0; i < length; ++ i){cout << ((code & (1 << i)) ? 1 : 0);}cout << endl;cout << "the hamming code " << result << "[" << reLen << "] ";for (int i = 0; i < reLen; ++ i){cout << ((result & (1 << i)) ? 1 : 0);}cout << endl;cout << "now to test the result " << endl;// test and indicate which bit is wrong// notice the binary number should be reversed// when you want to know the decimal valuefor (int i = 0; i < reLen; ++ i){int test = result & ~(1 << i);// result & ( 1 << i);int errLoc;Encode::CheckCode(test,reLen, errLoc);cout << test << " " << errLoc;cout << ' ';}cout << endl;return 0;
}

一个开源的C demo

// ------------------------------------------------------------------------
// File:    hamming.c
// Date:    August 7, 2000
//
// Encoding and decoding of a Hamming code. 
// ------------------------------------------------------------------------
// This program is complementary material for the book:
//
// R.H. Morelos-Zaragoza, The Art of Error Correcting Coding, Wiley, 2002.
//
// ISBN 0471 49581 6
//
// This and other programs are available at http://the-art-of-ecc.com
//
// You may use this program for academic and personal purposes only. 
// If this program is used to perform simulations whose results are 
// published in a journal or book, please refer to the book above.
//
// The use of this program in a commercial product requires explicit
// written permission from the author. The author is not responsible or 
// liable for damage or loss that may be caused by the use of this program. 
//
// Copyright (c) 2002. Robert H. Morelos-Zaragoza. All rights reserved.
// ------------------------------------------------------------------------#include <math.h>
#include <stdio.h>
#include <float.h>
#include <limits.h>
#include <stdlib.h>
#include <cstdlib>
#define MAX_RANDOM LONG_MAX    // Maximum value of random() int i,j,l,index;
int n, k;
int code[1024];
int red[1024], info[1024];
int m;
int parity[10];
int syn;
int error;int test, result;main(int argc, char *argv[])
{if (argc != 3){printf("Usage: %s   m   position_error\n", argv[0]);exit(0);}sscanf(argv[1],"%d",  &m);sscanf(argv[2],"%d",  &error);n = pow(2,m)-1; k = n - m;// Compute parity positionsparity[1] = 1;for (i=2; i<=m; i++)parity[i] = (parity[i-1]<<1) & 0xfffffffe;printf("parity positions: ");for (i=1; i<=m; i++) printf("%2d ", parity[i]); printf("\n");// Generate random messagefor (i=1; i<=k; i++)info[i] = ( random() >> 10) & 0x01;printf("information bits = ");for (j=1; j<=k; j++) printf("%1d", info[j]);printf("\n");// Compute parity bitsfor (j=1; j<=m; j++){red[j] = 0;l = 0;for (i=1; i<=n; i++){// Check that "i" is not a parity position = not a power of 2result = 0;test = 1;for (index=1; index<=m; index++){if (i==test) result = 1;test *= 2;}if (!result){l++;if ( (i>>(j-1)) & 0x01 )red[j] ^= info[l];}}}printf("parity bits = ");for (j=1; j<=m; j++) printf("%1d", red[j]);printf("\n");// Transmit codewordi = 1;l = 1;for (j=1; j<=n; j++)if (j==parity[l] && l<=m){code[j] = red[l]; l++;}else{code[j] = info[i]; i++;}printf("codeword = ");for (j=1; j<=n; j++) printf("%1d", code[j]);printf("\n");// Add a hard errorcode[error] ^= 1;printf("received = ");for (j=1; j<=n; j++) printf("%1d", code[j]);printf("\n");// Compute syndrome syn = 0;for (i=1; i<=n; i++)if (code[i]) syn ^= i;printf("syndrome = %d\n", syn);// Correct error if neededif (syn)code[syn] ^= 1;printf("estimate = ");for (j=1; j<=n; j++) printf("%1d", code[j]);printf("\n");}

没找到很好的算法实现源码,不知道有没有开源,如有开源的请留言

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV-Python bindings是如何生成的(1)

翻译自How OpenCV-Python Bindings Works? 目标 学习 OpenCV-Python bindings是如何生成的如何为Python扩展新的opencv模块 OpenCV-Python bindings是如何生成的 在OpenCV里&#xff0c;所有算法都是用C实现的。但是这些算法可以在别的语言里使用&#xff0c;比如Python&…

OpenCV-Python bindings是如何生成的(2)

OpenCV-Python bindings生成流程 通过上篇文章和opencv python模块中的CMakeLists.txt文件&#xff0c;可以了解到opencv-python bindings生成的整个流程: 生成headers.txt文件 将每个模块的头文件添加到list中&#xff0c;通过一些关键词过滤掉一些不需要扩展的头文件&#x…

【TensorFlow】学习资源汇总以及知识总结

官方资源 官方网站 https://tensorflow.org 非翻墙神器不能访问也&#xff08;关键是我用了翻墙神器也没能访问&#xff09;伪官方网站 https://tensorflow.google.cn/ 墙内的人可以查阅的资料github https://github.com/tensorflow/tensorflow官方提供的models以及tutorial h…

机器学习资源锦集

http://www.cnblogs.com/pinard 十年码农&#xff0c;对数学统计学&#xff0c;数据挖掘&#xff0c;机器学习&#xff0c;大数据平台&#xff0c;大数据平台应用开发&#xff0c;大数据可视化感兴趣。github 深度学习 【深度学习】批归一化&#xff08;Batch Normalization&…

获取训练数据的方式

下载搜狗词库 https://pinyin.sogou.com/dict/ 在官网搜索相关的词库下载&#xff0c;比如地名等&#xff0c;然后使用脚本将此条转换成txt保存&#xff0c; 来源 # -*- coding: utf-8 -*- import os import sys import struct # 主要两部分 # 1.全局拼音表&#xff0c;貌似…

浅谈python MRO与Mixin模式

MRO(Method Resolution Order) In object-oriented programming languages with multiple inheritance, the diamond problem (sometimes referred to as the “deadly diamond of death”) is an ambiguity that arises when two classes B and C inherit from A, and class D…

CentOS7开发环境搭建(2)

关闭SELinux # 查看 $ getenforce Disabled $ sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: …

IntelliJ IDEA开发环境应用

安装 下载windows压缩包获取帮助: idea.medeming.com/jihuoma 常用设置 全局设置&#xff0c;对新建的工程生效 【File】【Other Settings】【Setings for New Projects…】 比如配置maven的路径以及配置文件的路径&#xff0c;基本设置一次即可&#xff0c;不需要每次新建工…

tcp状态机-三次握手-四次挥手以及常见面试题

TCP状态机介绍 在网络协议栈中&#xff0c;目前只有TCP提供了一种面向连接的可靠性数据传输。而可靠性&#xff0c;无非就是保证&#xff0c;我发给你的&#xff0c;你一定要收到。确保中间的通信过程中&#xff0c;不会丢失数据和乱序。在TCP保证可靠性数据传输的实现来看&am…

Visual studio Code的C/C++开发环境搭建

文章目录VS CodeC/C环境配置环境准备使用实例基于 VSCode 的远程开发平台环境准备参考VS Code Visual Studio Code&#xff08;简称VS Code&#xff09;是一个由微软开发&#xff0c;同时支持Windows 、 Linux和macOS等操作系统且开放源代码的代码编辑器&#xff0c;它支持测试…

Linux网络编程--文件描述符

文件描述符 在Unix和Unix-like操作系统中&#xff0c;文件描述符(file descriptor, FD)是一个文件或者像pipe或者network socket等之类的输入/输出源的唯一标识。 文件描述符通常是一个非负整数&#xff0c;负数通常代表无值或者错误。 文件描述符是POSIX API的一部分。每个除…

深信服 linux软件开发面试题整理

1、结构体可以进行比较 int memcmp ( const void * ptr1, const void * ptr2, size_t num ); Compare two blocks of memory Compares the first num bytes of the block of memory pointed by ptr1 to the first num bytes pointed by ptr2, returning zero if they all match…

大端小端模式判断以及数据转换

简介 在计算机系统中&#xff0c;我们是以字节为单位的&#xff0c;每个地址单元都对应着一个字节&#xff0c;一个字节为 8bit。但是在C语言中除了8bit的char之外&#xff0c;还有16bit的short型&#xff0c;32bit的long型&#xff08;要看具体的编译器&#xff09;&#xff…

MSYS2下搭建Qt开发环境

最近随意浏览了一下俺们大省会城市的招聘信息&#xff0c;发现C招聘中涉及Qt经验的要求有不少&#xff0c;为了牛奶和面包&#xff0c;决心深入一下Qt开发。本篇文章由此而出。 Qt 关于Qt的人生经历在这不在累赘&#xff0c;资料随处可得&#xff0c;这里只记录干货。 环境搭…

CentOS7开发环境搭建(1)

文章目录BIOS开启VT支持U盘安装系统(2019-03-11)CentOS DNS配置CentOS网络配置配置静态IP克隆虚拟机网卡名称变更 CentOS6.5时间配置安装VMWare-tools用户管理 (2019-03-15 7.6.1810)给一般账号 root 权限Samba服务配置安装必备软件获取本机公网ipyum源和第三方库源管理配置本地…

ACM 欧拉公式

给出一个数X&#xff0c;求小于X的与X互质的数的个数&#xff0c;使用欧拉公式。 如果x1*x2*...*xnX,则个数nX*(1-1/x1)*(1-/x2)*... 使用这个的题目&#xff0c;超典型 相遇周期(HDOJ)

HDU 1495 非常可乐(BFS)

思路 最难在于想到这道题是BFS&#xff0c;想到之后只有六种情况就很好理解了。 代码 #include<stdio.h> #include<string.h> #include<math.h> #include<queue> using namespace std; int a,b,s; struct shui {int count;int ha,hb,hs; }t,t1; int m…

NBU计算机专业期末考试记录

考试科目&#xff1a;操作系统 软件工程 数据库 计算机网络 JAVA高级应用 汇编 计算机算法设计 操作系统&#xff1a;题目比较简单&#xff0c;这学期的大题有写读写互斥的代码、求平均磁道数、银行家算法、页面调度算法的缺页次数计算。期中考试有参考价值&#xff0c;要看懂…

蚁群算法的若干记录

1、蚁群算法的特点&#xff1a; ① 结合了分布式算法、正反馈机制、贪婪式搜索的算法&#xff1a;正反馈可以快速发现较优解、分布式算法避免早熟收敛、贪婪式搜索有助于早期找出可解决方案&#xff1b; ② 蚁群算法具有很强的并行性&#xff1b; ③ 个体之间通过信息素合作…

蚁群算法之二

1、蚂蚁系统模型的建立 给定G(V,A)&#xff0c;其中V为定点集&#xff0c;A为各顶点互相连接组成的边集,已知各顶点之间的连接距离&#xff0c;要求确定一条长度最短的回路&#xff0c;仅遍历一次所有顶点的回路。引入记号&#xff1a; m&#xff1a;蚁群中蚂蚁的数量&#x…