文章目录

实验题:

B.78 Hamming(7,4)编译码器

算法:Hamming(7,4)码的生成矩阵为

1
2
3
4
1 0 0 0 1 0 1
0 1 0 0 1 1 0
0 0 1 0 1 1 1
0 0 0 1 0 1 1

其校验矩阵为

1
2
3
1 1 1 0 1 0 0
0 1 1 1 0 1 0
1 0 1 1 0 0 1

要求:

允许使用的编程语言:c、c++、Basic、pascal、fortran、java、tk/tcl。

输入:长度为4的任意二进制序列。

输出:输入数据经Hamming(7,4)编码器编码之后,通过B.7节的BSC信道(错误概率为0.1)传输后,再经过Hamming(7,4)译码器输出得到信宿端的长度为4的二进制序列。

源程序格式整齐清晰,注释简单明了。

分析:

Hamming编译码的原理很简单,通过键盘输入一四位的二进制待传序列,存入input[]内。然后让input[]与已经定义好的生成矩阵create[][]进行乘法运算,得到真正要送入BSC模拟信道传输的二进制序列,存入transcode[]中。送入BSC模拟信道进行模拟传输后返回传输结果,结果覆盖存储于transcode[]中,下面进行译码过程。

译码过程也很简单,原理参见教材pg151,其思路是先求出伴随式S,然后再根据伴随式S求出差错图样E,最后将差错图样E与信道模拟传输的结果相加,得到发码C的估值,最后输出其前四位即为所要求的输出。

由于译码过程中其他步骤无技术难度故略,下面着重解释从伴随式S得到差错图样E的过程。本题恰好为hamming(7,4)码,故可以用比对法直接找出错误图样。将伴随式S与校验矩阵check[][]的每一列进行比较,如果两数值相等,则将compare[][]矩阵对应位置置为1,否则置为0。再通过比对compare[][]矩阵每一列的三个数是否是否全部相等且为1(表示校验矩阵这一列与伴随式S完全相同),若满足则表示此位发生传输错误,置错误图样E[]矩阵对应位置为1,否则置为0,由此便得到了错误图样E。
模拟BSC信道不在本题考虑范围,故略。

源代码:

#include<stdlib.h>
#include<iostream.h>
#include<time.h>
void main()
{
int input[4]; /*定义输入矩阵*/
int i;
int j;
float p=10;
int create[4][7]={1,0,0,0,1,0,1,0,1,0,0,1,1,0,0,0,1,0,1,1,1,0,0,0,1,0,1,1}; /*定义生成矩阵*/
int check[3][7]={1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,0,1,1,0,0,1}; /*定义校验矩阵*/
int transcode[7]={0,0,0,0,0,0,0};/*定义编码后待传输的矩阵*/
int S[3]={0,0,0};/*定义伴随式*/
int E[7]={0,0,0,0,0,0,0};/*定义差错图样*/
int fittingtcode[7];/*定义发码C的估值*/
int compare[3][7]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};/*定义下文需要用到的比较矩阵*/
void bsc(int c[],float x);
/*——————给出题设———————-*/
cout<<”Hamming(7,4)编码器的生成矩阵是:”<<endl;
for(i=0;i<=3;i++)
{
for(j=0;j<=6;j++)
{
cout<<create[i][j]<<” ”;
}
cout<<endl;
}
cout<<”其校验矩阵是:”<<endl;
for(i=0;i<=2;i++)
{
for(j=0;j<=6;j++)
{
cout<<check[i][j]<<” ”;
}
cout<<endl;
}
cout<<”BSC信道的错误概率是:0.1″<<endl;
/*输入信息序列*/
cout<<”请输入待传输的信息序列(长度为4,以空格分隔):”<<endl;
for(i=0;i<=3;i++)
{
cin>>input[i];
}
cout<<”输入的待传输序列是:”;
for(i=0;i<=3;i++)
{
cout<<input[i];
}
/*计算编译hamming码,存入transcode*/
for(i=0;i<=6;i++)
{
for(j=0;j<=3;j++)
{
transcode[i]=(input[j]*create[j][i]+transcode[i])%2;
}
}
cout<<endl;
cout<<”经编译后需传入BSC信道的数据为:”;
for(i=0;i<=6;i++)
{
cout<<transcode[i];
}
cout<<endl;
/*送入模拟信道*/
cout<<”——————正在送入模拟BSC信道——————”<<endl;
bsc(transcode,p);
cout<<”经模拟后输出的二进制序列为:   ”;
for(i=0;i<=6;i++)
{
cout<<transcode[i];
}
cout<<endl;
/*开始译码*/
cout<<”——————开始进行译码过程——————”<<endl;
/*计算伴随式*/
for(i=0;i<=2;i++)
{
for(j=0;j<=6;j++)
{
S[i]=(transcode[j]*check[i][j]+S[i])%2;
}
}
cout<<”伴随式为S:”;
for(i=0;i<=2;i++)
{
cout<<S[i];
}
cout<<endl;
/*通过与校验矩阵比对获得差错图样E*/
for(i=0;i<=6;i++)
{
for(j=0;j<=2;j++)
{
if(S[j]==check[j][i]) compare[j][i]=1;
else compare[j][i]=0;
}
}
for(i=0;i<=6;i++)
{
if(compare[0][i]==compare[1][i]&compare[0][i]==compare[2][i]&compare[0][i]==1) E[i]=1;
}
cout<<”差错图样E是:”;
for(i=0;i<=6;i++)
{
cout<<E[i];
}
cout<<endl;
/*将差错图样E与传来的码R相加,得到C的估值*/
for(i=0;i<=6;i++)
{
fittingtcode[i]=(transcode[i]+E[i])%2;
}
cout<<”最后译码输出的最终结果(传送序列的估计值)为:”;
/*最后输出估值的前四位,即为待输出的数据*/
for(i=0;i<=3;i++)
{
cout<<fittingtcode[i];
}
cout<<endl;
}
/*独立的BSC模拟函数*/
void bsc(int c[], float x){
int i;
int r;
srand(time(0));
for(i=0;i<=9;i++)
{
r=rand()%100+1;
if (r>=x)
{         /*表示进入正确区间*/
c[i]=c[i];
}
else
{           /*表示进入错误区间*/
if(c[i]==0)
c[i]=1;
else c[i]=0;
}
}
}

实验结果:

Test1:

Test2:

Test3:

总结:

通过本实验加深了我对hamming编码的以及纠检错码的认识与理解,充分认识到纠检错的重要意义。

在编程过程中关于求差错图样E,本来打算用逆矩阵利用公式来计算,后发现题目中给出的校验矩阵不是方阵,计算逆矩阵比较麻烦。后经过观察发现本题恰好为hamming(7,4)码,检验矩阵的7列恰好为除了(0 0 0)外的其他7种伴随式,故只要进行比对即可得出差错图样E,因而本代码所给出的解决方法不具有通用性,只适合本题。

实验在调试阶段还有一有趣的小插曲,在调试的时候,前几次一直很正常,但有一组数据当模拟BSC信道传输出现2个差错时最后译码输出的结果和实际输入的结果大相径庭。一开始我还以为程序有错误,到处下断点找错误,结果后来恍然大悟。观察题目所给校验矩阵发现编的这个译码器只有1位纠错能力,发生两位错误当然无法正确译码。


如果觉得文章很有趣或对你带来了帮助,欢迎请我喝杯咖啡哦~

文章目录