0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

汉明码原理和校验及实现

倩倩 来源:网络整理 2018-03-02 15:20 次阅读

汉明码原理介绍:

在计算机运行过程中,由于种种原因导致数据在存储过程中可能出现差错,为了能够及时发现错误并且将错误纠正,通常可以将原数据配成汉明编码。

汉明码具有一位纠错能力。

奇偶校验是一种添加一个奇偶位用来指示之前的数据中包含有奇数还是偶数个1的检验方式。如果在传输的过程中,有奇数个位发生了改变,那么这个错误将被检测出来(注意奇偶位本身也可能改变)。一般来说,如果数据中包含有奇数个1的话,则将奇偶位设定为1;反之,如果数据中有偶数个1的话,则将奇偶位设定为0。换句话说,原始数据和奇偶位组成的新数据中,将总共包含偶数个1.

奇偶校验并不总是有效,如果数据中有偶数个位发生变化,则奇偶位仍将是正确的,因此不能检测出错误。而且,即使奇偶校验检测出了错误,它也不能指出哪一位出现了错误,从而难以进行更正。数据必须整体丢弃并且重新传输。在一个噪音较大的媒介中,成功传输数据可能需要很长时间甚至不可能完成。虽然奇偶校验的效果不佳,但是由于他只需要一位额外的空间开销,因此这是开销最小的检测方式。并且,如果知道了发生错误的位,奇偶校验还可以恢复数据。

如果一条信息中包含更多用于纠错的位,且通过妥善安排这些纠错位使得不同的出错位产生不同的错误结果,那么我们就可以找出出错位了。在一个7位的信息中,单个数据位出错有7种可能,因此3个错误控制位就足以确定是否出错及哪一位出错了。

汉明编码方案通用算法

下列通用算法可以为任意位数字产生一个可以纠错一位的汉明码。

一、1开始给数字的数据位(从左向右)标上序号, 1,2,3,4,5.。。

二、将这些数据位的位置序号转换为二进制,1, 10, 11, 100, 101,等。

三、数据位的位置序号中所有为二的幂次方的位(编号1,2,4,8,等,即数据位位置序号的二进制表示中只有一个1)是校验位

四、有其它位置的数据位(数据位位置序号的二进制表示中至少2个是1)是数据位

五、每一位的数据包含在特定的两个或两个以上的校验位中,这些校验位取决于这些数据位的位置数值的二进制表示

1.校验位1覆盖了所有数据位位置序号的二进制表示倒数第一位是1的数据:1(校验位自身,这里都是二进制,下同),11,101,111,1001,等

2.校验位2覆盖了所有数据位位置序号的二进制表示倒数第二位是1的数据:10(校验位自身),11,110,111,1010,1011,等

3.校验位4覆盖了所有数据位位置序号的二进制表示倒数第三位是1的数据:100(校验位自身),101,110,111,1100,1101,1110,1111,等

4.校验位8覆盖了所有数据位位置序号的二进制表示倒数第四位是1的数据:1000(校验位自身),1001,1010,1011,1100,1101,1110,1111,等

5.简而言之,所有校验位覆盖了数据位置和该校验位位置的二进制与的值不为0的数。 采用奇校验还是偶校验都是可行的。偶校验从数学的角度看更简单一些,但在实践中并没有区别。

从编码形式上,我们可以发现汉明码是一个校验很严谨的编码方式。在这个例子中,通过对4个数据位的3个位的3次组合检测来达到具体码位的校验与修正目的(不过只允许一个位出错,两个出错就无法检查出来了,这从下面的纠错例子中就能体现出来)。在校验时则把每个汉明码与各自对应的数据位值相加,如果结果为偶数(纠错代码为0)就是正确,如果为奇数(纠错代码为1)则说明当前汉明码所对应的三个数据位中有错误,此时再通过其他两个汉明码各自的运算来确定具体是哪个位出了问题。

汉明码原理和校验及实现

观察上表可发现一个比较直观的规律:第i个检验位是第2i-1位,从该位开始,检验2i-1位,跳过2i-1位……依次类推。例如上表中第3个检验位p4从第23-1=4位开始,检验4、5、6、7共4位,然后跳过8、9、10、11共4位,再检验12、13、14、15共4位……

汉明码的编码规则如下:

在新的编码的2^(k - 1)( k 》= 0)位上填入0(即校验位)

把新的编码的其余位把源码按原顺序填入

校验位的编码方式为:第k位校验码从则从新的编码的第2^(k - 1)位开始,每计算2^(k - 1)位的异或,跳2^(k - 1)位,再计算下一组2^(k - 1)位的异或,填入2^(k - 1)位,比如:

第1位校验码位于新的编码的第1位(2 ^(1-1) == 1)(汉明码从1位开始),计算1,3,5,7,9,11,13,15,。。。位的异或,填入新的编码的第1位。

第2位校验码位于新的编码的第2位(2 ^(2-1) == 2),计算2,3,6,7,10,11,14,15,。。。位的异或,填入新的编码的第2位。

第3位校验码位于新的编码的第4位(2 ^(3-1) == 4),计算4,5,6,7,12,13,14,15,20,21,22,23,。。。位的异或,填入新的编码的第4位。

第4位校验码位于新的编码的第8位(2 ^(4-1) == 8),计算8-15,24-31,40-47,。。。位的异或,填入新的编码的第8位。

第5位校验码位于新的编码的第16位(2 ^(5-1) == 16),计算16-31,48-63,80-95,。。。位的异或,填入新的编码的第16位。

在数学方面,汉明码是一种二元线性码。对于每一个整数m》2,存在一个编码,带有m个奇偶校验位2m- m-1个数据位。

汉明码的生成和检验

设将要进行检测的二进制代码为n位,为使其具有纠错能力,需要再加上k位的检测位,组成n+k位的代码。那么,新增加的检测位数k应满足:

2k≥n+k+1或2k-1≥n+k

汉明码原理和校验及实现

当k的位数确定后,便可根据承担的检测任务设定他们在传送代码中的位置和他们的取值。首先,将所要检测的代码分为Pn组,分多少个组,我们通过k的值来确定。下面我用一个例子来说明。

假设将要进行检测的二进制代码为0101,位数n=4,根据公式2k≥n+k+1可以得出k的值是3,所以最终形成的汉明码应为n+k=7位。

所以分组分为P1、P2、P4。原因则是第一组是20、第二组则是21 、同理第三组则是22 、依次列推分组应按照2k-1。同时以后根据分组产生的数插入的位置也是按照此规律插入,比如第一组插入20、即第1位,第二组插入21 、即第2位,以此类推。那么组分好了,他们每一组中包含的位则是:

p1包含(1,3,5,7,9,11,。。。位)

p2包含(2,3,6,7,10,11,14,15,。。。位)

p3包含(4,5,6,7,12,13,14,15,。。。位)

每一组中包含的数又是如何确定的呢?我们来看下面这个表格

汉明码原理和校验及实现

将编号转成二进制从右向左,如果第一位是1,例如编号是1,3,5,7.。。。的就分入第一组,如果第二位是1的,例如编号2,3,6,7,10.。。的就分入第二组,以此类推将所有的编号分入相应的组中。下面我么来看例子0101是如何产生汉明码的(采用配偶原则),

汉明码原理和校验及实现

其中C1、C2、C4是我们插入的检测位

如果按照配偶原则来配置汉明码,则C1应使1 3 5 7位中“1”的个数为偶数;C2应使2 3 6 7位中“1”的个数为偶数;C4应使4 5 6 7位中“1”的个数为偶数。

按照上面我所说的则:

C1=③位+⑤位+⑦位,即C1=B4+B3+B1=0+1+1=0

C2=③位+⑥位+⑦位,即C2=B4+B2+B1=0+0+1=1

C4=⑤位+⑥位+⑦位,即C4=B3+B2+B1=1+0+1=0

所以0101的汉明码应为C1C2B4C4B3B2B1,即0100101

汉明码还存在配奇原则,下面来讲一讲配奇原则。按照配奇原则配置1100101的汉明码。

根据1100101可知n=7。根据公式我们可以求出需要添加k=4位检测位,详细情况如下表。

汉明码原理和校验及实现

按配奇原则配置,则

C1=③位+⑤位+⑦位+⑨位+11位+1=1+1+0+1+1+1=1

C2=③位+⑥位+⑦位+10位+11位+1=1

C4=⑤位+⑥位+⑦位+1=0

C8=⑨位+10位+11位+1=1

所以按配奇原则新配置的汉明码为11101001101

汉明码校验错误实例

我们以上面的编码为例,假设我们现在收到的编码为001101001,我们可以发现汉明码的第8位与原来的汉明码001101011不同,那我们怎么找出这个第8位的错误编码呢?

算法很简单,我们只要在算汉明码校验位的算法的上再算一遍,就得到了汉明码的校验方法,比如计算001101001对应的2^k位。

1,3,5,7,9进行异或,得到0

2,3,6,7进行异或,得到0

4,5,6,7进行异或,得到0

8,9进行异或,得到1

我们把上述结果反着排列,得到1000,即十进制的8,根据汉明码的校验规则,编码出错的地方即在第8位,我们把第8位的0换成1,即可得原来的编码001101011。

上述的例子是出现在2^k的校验位上的,如果出现在非2^k位上,得到的结果也是一样的,比如:

假设收到的编码为001100011,即第6位出了错误,我们根据规则

1,3,5,7,9进行异或,得到0

2,3,6,7进行异或,得到1

4,5,6,7进行异或,得到1

8,9进行异或,得到0

我们把上述结果反着排列,得到0110,即十进制的6,根据汉明码的校验规则,编码出错的地方即在第6位,我们把第6位的0换成1,即可得原来的编码001101011。

汉明码的编码和校验的C++实现

通过原理,我们可以很简单地实现汉明码的编码和校验代码

auto cal(size_t sz)-》decltype(auto)

{

decltype(sz) k = 0;

decltype(sz) cur = 1;

while (cur - 1 《 sz + k )

{

cur 《《= 1;

k++;

}

return k;

}

bool encode(const string &s, string &d)

{

d.clear();

auto k = cal(s.size());

d.resize(s.size() + k);

for (decltype(d.size()) i = 0, j = 0, p = 0; i!= d.size();i++)

解码与校验:

auto antiCal(size_t sz)-》decltype(auto)

{

decltype(sz) k = 0;

decltype(sz) cur = 1;

while (cur 《 sz)

{

cur 《《= 1;

k++;

}

return k;

}

auto decode(string &s, string &d)-》decltype(auto)

{

s.clear();

auto k = antiCal(d.size());

s.resize(d.size() - k);

decltype(d.size()) sum = 0;

for (decltype(k) p = 0;p != k;p++)

{

int pAnti = 0;

decltype(k) index = 1 《《 p;

for (decltype(d.size()) i = index - 1;i 《 d.size(); i+=index)

{

for (auto j = 0; j 《 index && i 《 d.size(); i++, j++)

pAnti ^= d[i] - ‘0’;

}

sum += pAnti 《《 p;

}

if (sum != 0)

d[sum - 1] = (1- (int)(d[sum - 1] - ‘0’)) + ‘0’;

for (decltype(d.size()) i = 0, p = 0,j = 0; i != d.size(); i++)

{

if ((i + 1) == (1 《《 p) && p 《 k)

p++;

else

s[j++] = d[i];

}

return sum;

}

{

if ((i + 1) == pow(2,p) && p 《 k)

{

d[i] = ‘0’;

p++;

}

else if (s[j] == ‘0’ || s[j] == ‘1’)

d[i] = s[j++];

else

return false;

}

for (auto i = 0; i != k;i++)

{

int count = 0 ,index = 1 《《 i;

for (auto j = index - 1; j 《 d.size() ;j += index)

for (auto k = 0; k!= index && j 《 d.size(); k++, j++)

count ^= d[j] - ‘0’;

d[index - 1] = ‘0’ + count;

}

return true;

}

测试样例:

int main()

{

string source, dest;

while (cin 》》 source)

{

if (encode(source,dest))

{

cout 《《 “Source: ” 《《source 《《 endl;

cout 《《 “Dest: ” 《《 dest 《《 endl;

}

size_t index;

cout 《《 “----input error index : ”;

cin 》》 index;

auto k = dest.size();

if (index != 0 && index 《= dest.size())

dest[index - 1] = (1 - (int)(dest[index - 1] - ‘0’)) + ‘0’;

cout 《《 “Code ” 《《 dest 《《endl;

auto ret = decode(source,dest);

if (ret == 0)

{

cout 《《 “Source: ” 《《source 《《 endl;

cout 《《 “Dest: ” 《《dest 《《 endl;

}

else

{

cout 《《 “Error index ”《《 ret 《《 endl;

cout 《《 “Corret source: ” 《《source 《《 endl;

cout 《《 “Corret dest: ” 《《dest 《《 endl;

}

cout 《《 endl;

}

return 0;

}

Source: 10101

Dest: 001101011

----input error index : 8

Code 001101001

Error index 8

Corret source: 10101

Corret dest: 001101011

Source: 1001010101010101010111111001101

Dest: 1111001101010100101010101111110101101

----input error index : 20

Code 1111001101010100101110101111110101101

Error index 20

Corret source: 1001010101010101010111111001101

Corret dest: 1111001101010100101010101111110101101

Source: 1

Dest: 111

----input error index : 0

Code 111

Source: 1

Dest: 111

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 汉明码
    +关注

    关注

    0

    文章

    8

    浏览量

    8061
收藏 人收藏

    评论

    相关推荐

    请问汉明码(7,4)一共有多少种码字呢?

    我觉得应该是2^4=16种吧?汉明码(12,8)就是2^8=256种?请问对不对?
    发表于 05-22 00:09

    三菱PLC和校验计算器

    三菱PLC和校验计算器
    发表于 07-21 15:59

    和校验遇到数据校验不到而导致出错

    串口发送数据时,利用和校验的方法对数据进行校验,但是遇到数据校验不到而导致出错,请问这种情况该如何解决?
    发表于 04-14 23:04

    基于FPGA的汉明码译码器如何对码元数据添加噪声干扰?

    的?还有这篇文章是2010年发表的了,如今汉明码译码器的FPGA实现是否有更好的实现方法呢?有大神可以给我提供一个思路吗?or2万分感谢
    发表于 02-26 23:29

    【原创】基于FPGA的汉明码编码解码设计

    基于FPGA的汉明码编码解码设计实验简述本实验的目的是实现汉明纠错码的编码和解码1.1汉明码简介 汉明码,是在电信领域的一种线性调试码,以发明者理查德 卫斯理 汉明的名字命名。
    发表于 04-15 11:47

    如何提高汉明码的纠错能力?

    汉明码纠错原理是什么?怎样实现汉明码对连续多位差错纠正?怎样去设计汉明码测试程序?
    发表于 04-27 06:22

    提高汉明码对突发干扰的纠错能力

    在简要介绍汉明码编码原理的基础上,详细分析干扰对汉明码纠错的影响;通过对汉明码重新组织排列,在不增加代码冗余度的前提下,提高汉明码抗突发干扰的能力,为
    发表于 04-15 11:34 20次下载

    一种基于汉明码和湿纸码的隐写算法

    该文通过将载体图像分割成矩阵块,重复利用载体矩阵块像素,结合汉明码和湿纸码构造了一种新的双层结构隐写算法。该算法首先利用汉明码在载体矩阵的行向量中嵌入信息,然
    发表于 02-09 14:45 8次下载

    汉明码,汉明码是什么意思

    汉明码,汉明码是什么意思 汉明码是一种能够纠正单个错误的线性分组码。它有以下特点: (1)最小码距
    发表于 03-17 17:41 8381次阅读

    基于FPGA的检纠错逻辑算法的实现

    基于汉明码的纠错原理.根据对64位数据进行检纠错处理的需要,设计一个利用8位校验码,以实现该功能的算法逻辑,并通过FPGA实现
    发表于 09-15 15:14 1581次阅读
    基于FPGA的检纠错逻辑算法的<b class='flag-5'>实现</b>

    汉明码计算及其纠错原理详解

    汉明码(Hamming Code),是在电信领域的一种线性调试码,以发明者理查德·卫斯里·汉明的名字命名。汉明码在传输的消息流中插入验证码,以侦测并更正单一比特错误。由于汉明编码简单,它们被广泛应用于内存(RAM )。
    的头像 发表于 03-02 15:08 2.9w次阅读
    <b class='flag-5'>汉明码</b>计算及其纠错原理详解

    汉明码编译码器的数据手册免费下载

    本文档的主要内容详细介绍的是汉明码编译码器的数据手册免费下载。
    发表于 12-13 08:00 0次下载
    <b class='flag-5'>汉明码</b>编译码器的数据手册免费下载

    汉明码纠错的基本原理及优化解决方案

    我们也要看到,这样处理后提高了汉明码对突发干扰差错的纠错能力,却牺牲了对随机干扰纠错能力。因为这样对汉明码重新排序后,原来1个汉明码的各个位分布在不同位置的字节里,当有多个随机干扰出现时,可能使原来
    的头像 发表于 09-16 17:52 1.5w次阅读
    <b class='flag-5'>汉明码</b>纠错的基本原理及优化解决方案

    流量计零位检查和校验注意事项

    关断切断阀对流量零位示值进行检查和校验是流量示值验证的首要任务。这是因为流量计零位如果不准,将对量程范围内的各点示值都产生影响。在作零位检查和校验时应注意以下事项。
    的头像 发表于 10-09 08:11 2276次阅读

    汉明码编译码文档

    电子发烧友网站提供《汉明码编译码文档.doc》资料免费下载
    发表于 11-17 16:04 2次下载
    <b class='flag-5'>汉明码</b>编译码文档