一、通信相关知识
数字通信时候从差错控制角度看,信号可以分为三类:
1、随机信道--------在随机信道中,错误码出现时随机的,且错误码之间是统计独立的;
2、突发信道--------错误码是成串集中出现的;
3、混合信道--------存在随机错误和突发错误两种错误码;
常用的差错控制方法:
1、检错重发--------接收方在收到的信息码中检测到错误,即通知发送端重发,直到正确收到为止;
2、前向纠错--------接收端不仅能发现错误码,还能够确定错误码的位置,能够纠正它;
3、反馈校验--------接收端讲收到的信息码原封不动的传回发送端与原码元比较,若发现错误则重发;
那么接收端根据什么来识别有无错误码呢?
由发送端的信道编码器在信息码元的循序中增加一些监督码元。这些监督码元和信息码之间有确定的关系,使接收端可以
利用这种确定关系由信道译码器来发现或者纠正可能存在的错误码。
二、汉明码简介
汉明码,(Hamming Code)是由Richad Hamming1950年提出的,它具有检错并纠正一位错误的能力,适合引发随机错误,
且错误间没有相互关系的信道。如果信息原始长度为m,设监督码元长度为k,则总码长n=m+k,且要满足如下不等式:
2^k>=m+k+1;
1、码距的概念
汉明码距指的是长度相同的两个符号序列(码字)a和b之间对应位置上不同码元的个数,用符号D(a,b)表示,如两个二元序列:
a=101111
b=111100
则得D(a,b)=3。
有了汉明码距的概念,我们就可以用汉明码距来描述码的纠错检测能力。如果一组编码的码长为n,将这些资源全部利用上,可以对2^n个符号进行编码,但这样一来这个编码就没有任何抗干扰能力,因为合法码字之间的最小汉明码距为1,任何一个符号的编码的任意一位发生错误,就变成了另外一个符号的编码,它也是一个合法的码字。接收端不能判断是不是有错误发生。
我们可以在2^n个可用的码字中间选择一些码字来对信源符号进行编码,把这些码字称为合法码字,而其他没有使用的码字称为非法码字。这样合法码字之间的汉明距离就会拉开,有些合法码字发生错误后有可能变成非法码字,接收端收到这些非法码字后就可以判断出传输过程中出现了错误。码字之间的最小汉明距离越大,编码的抗干扰能力就越强。如果编码的最小汉明距离为2,那么任何合法码字发生一位错误都会变成非法码字,但不能确定是由哪一个合法码字错误而来,因此这个编码可以发现一位错误;如果编码的最小汉明距离为3,那么任何合法码字发生一位错误都会变成非法码字,而且距离原来的码字距离为1,而距离其他任何合法码字的最小距离为2,因此可以确定这个非法码字是由哪一个合法码字发生错误而来,这个编码用作纠错编码可以发现一位错误并纠正一位错误。如果发生了两位错误,也可以发现,但是如果试图纠正这个错误就会产生新的错误;如果把这种编码只当作检错编码,则可以发现两个错误。筇此类推,可以总结出编码的最小汉明码距与编码纠错检错能力之间的关系:
①要发现(检测)e个随机错误,则要求码的最小距离dmin≥e+1;
②要纠正e个随机错误,则要求码的最小距离dmin≥2e+1;
③要纠正e个随机错误,同时检测f(≥c)个错误,则要求码的最小距离dmin≥e+f+1。
如果一个分组码的数据位长度为k,校验位长度为r,总的编码长度为n,n=k+r,则总的可以编码的合法码字的个数为2^k,总的码字个数为2^n,可以看出,检验位的长度越长,合法码字所占的比例就越小,如果这些码字能够尽可能地在所有的码字中均匀分布的话,合法码字之间的最小汉明码距就越大,编码的抗干扰能力也就越强,因此设计编码方法的最重要的任务就是尽量使合法码字尽可能地均匀分布。
三、汉明码计算
暂时略,改天补上。
四、(7,4)汉明码C语言实现
汉明码C语言实现
unsigned char HMBM_74(unsigned char a)
{
unsigned char b =0;
b = a & 0x0F;
b = b <<0x03;
if(b&0x08){b=b^0x03;}
if(b&0x10){b=b^0x05;}
if(b&0x20){b=b^0x06;}
if(b&0x40){b=b^0x07;}
return(b & 0x7F);
}
unsigned char HMYM_74(unsigned char a)
{
unsigned char b=0,c=0;
b = a;
c = 0;
if(b&0x40) {c = c^0x07 ;}
if(b&0x20) {c = c^0x06 ;}
if(b&0x10) {c = c^0x05 ;}
if(b&0x08) {c = c^0x03 ;}
if(b&0x04) {c = c^0x04 ;}
if(b&0x02) {c = c^0x02 ;}
if(b&0x01) {c = c^0x01 ;}
switch(c){
case 0 :b = b >> 3 ;break ;
case 1 :b = b >> 3 ;break ;
case 2 :b = b >> 3 ;break ;
case 3 :b = (b^0x08) >> 3 ;break ;
case 4 :b = b >> 3 ;break ;
case 5 :b = (b^0x10) >> 3 ;break ;
case 6 :b = (b^0x20) >> 3 ;break ;
case 7 :b = (b^0x40) >> 3 ;break ;
}
return (b & 0x0F);
}
A+
Date:2016-12-14