(7,4)汉明码编译码原理程序说明书1、线性分组码假设信源输出为一系列二进制数字0和1.在分组码中,这些二进制信息序列分成固定长度的消息分组(message blocks )。
每个消息分组记为u ,由k 个信息位组成。
因此共有2k 种不同的消息。
编码器按照一定的规则将输入的消息u 转换为二进制n 维向量v ,这里n>k 。
此n 维向量v 就叫做消息u 的码字(codeword )或码向量(code vector )。
因此,对应于2k 种不同的消息,也有2k 种码字。
这2k 个码字的集合就叫一个分组码(block code )。
一个长度为n ,有2k 个码字的分组码,当且仅当其2k 个码字构成域GF (2)上所有n维向量空间的一个k 维子空间时被称为线性(linear )(n ,k )码。
对于线性分组码,希望它具有相应的系统结构(systematic structure ),其码字可分为消息部分和冗余校验部分两个部分。
消息部分由k 个未经改变的原始信息位构成,冗余校验部分则是n-k 个奇偶校验位(parity-check )位,这些位是信息位的线性和(linear sums )。
具有这样的结构的线性分组码被称为线性系统分组码(linear systematic block code )。
本实验以(7,4)汉明码的编译码来具体说明线性系统分组码的特性。
其主要参数如下:码长:21mn =-信息位:21mk m =-- 校验位:m n k =-,且3m ≥ 最小距离:min 03d d ==由于一个(n ,k )的线性码C 是所有二进制n 维向量组成的向量空间n V 的一个k 维子空间,则可以找到k 个线性独立的码字,0,1,1k g g g -…… ,使得C 中的每个码字v 都是这k 个码字的一种线性组合。
(7,4)汉明码的生成矩阵如下,前三位为冗余校验部分,后四位为消息部分。
0123 1 1 0 1 0 0 00 1 1 0 1 0 01 1 1 0 0 1 01 0 1 0 0 0 1g g G g g ⎧⎫⎧⎫⎪⎪⎪⎪⎪⎪⎪⎪==⎨⎬⎨⎬⎪⎪⎪⎪⎪⎪⎪⎪⎩⎭⎩⎭如果()0123u u u u u =是待编码的消息序列,则相应的码字可如下给出:()0101230011223323g g v u G u u u u u g u g u g u g g g ⎧⎫⎪⎪⎪⎪===+++⎨⎬⎪⎪⎪⎪⎩⎭编码结构即码字()0123456v v v v v v v v =,对于(7,4)线性分组码汉明码而言,3456,,,v v v v 为所提供的消息序列,而0356v v v v =⊕⊕,1345v v v v =⊕⊕,2456v v v v =⊕⊕。
由以上关系可以得到(7,4)汉明码的全部码字如下所示:2、用C++编写(7,4)汉明码编译码程序的思路如下: (1)编码程序循环输入待编码消息序列()0123u u u u u =,首先判断输入是否符合输入条件:输入必须是4位0,1序列,共有42种情况。
编码程序如下:(本人水平有限,使用直接赋值的方法,望见笑) for(j=0;j<7;j++) {if(j==3) v[j]= u[0];if(j==4) v[j]= u[1];if(j==5) v[j]= u[2];if(j==6) v[j]= u[3]; if(j==0)v[j]= ((u[0]^u[2])^u[3]); //异或运算 if(j==1)v[j]= ((u[0]^u[1])^u[2]); //异或运算 if(j==2)v[j]= ((u[1]^u[2])^u[3]); //异或运算 cout << v[j] << " "; }cout<<endl;编码的思想为: 30v u =41v u = 52v u =0356v v v v =⊕⊕ 1345v v v v =⊕⊕ 2456v v v v =⊕⊕(2)译码程序:循环输入待译码的码字序列()0123456v v v v v v v v =,第一步判断输入是否符合输入条件:输入必须是7位0,1序列,共有72种情况。
但是72种情况中只有42即16个有效码字,那么第二步则是要判断是否是42即16个有效码字,这也是编码的一个检错方式,利用其奇偶校验矩阵TH ,校正子s ,接收到的码字序列为r ,判断*Ts r H =是否等于0。
若等于0,则证明是有效码字;若不等于0,则证明不属于16个有效码字的一个。
● 奇偶校验矩阵100101101011100010111H ⎧⎫⎪⎪=⎨⎬⎪⎪⎩⎭● 奇偶校验矩阵100010001110011111101TH ⎧⎫⎪⎪⎪⎪⎪⎪⎪⎪=⎨⎬⎪⎪⎪⎪⎪⎪⎪⎪⎩⎭以下为纠错的关键程序:for(j=0;j<3;j++){a=(v[0]*ht[0][j])^(v[1]*ht[1][j])^(v[2]*ht[2][j])^(v[3]*ht[3][j])^(v[4]*ht[4][j])^(v[5]*ht[5][j])^(v[6]*ht[6][j]);result=result+a;}if(result!=0){cout<<"输入的是无效的字码"<<endl;goto loop;}else cout<<"输入字码有效"<<endl;cout<<"您所输入的待译码的码字序列为:";接下来便是译码的两个主要方法:第一个方法为查表法:程序中check_table()函数便是查表法。
第二个方法编码方法便是:系统码直接取信息位译码程序如下:for(j=0;j<4;j++){if(j==0)u[j]= v[3];if(j==1)u[j]= v[4];if(j==2)u[j]= v[5];if(j==3)u[j]= v[6];cout << u[j] << " ";}3、程序附录//(7,4)编译码程序#include <iostream>using namespace std;void check_table();//编码程序int main(){intg[4][7]={{1,1,0,1,0,0,0},{0,1,1,0,1,0,0},{1,1,1,0,0,1,0},{1,0,1,0,0,0,1}};//声明生成矩阵G,即4个线性独立的码字,可以使码本C中的码字v都是这k个码字的一种线性组合,int h[3][7]={{1,0,0,1,0,1,1},{0,1,0,1,1,1,0},{0,0,1,0,1,1,1}};//声明校验矩阵H,int ht[7][3]={{1,0,0},{0,1,0},{0,0,1},{1,1,0},{0,1,1},{1,1,1},{1,0,1}};//声明校验矩阵H的转置矩阵HT(这里的T是H 的上标)int u[4]; //声明待编码的消息序列,即未编码前的信息序列int v[7]; //声明编码后的码字序列//int s[7];int i,j,k;//顺序输入待编码4位信息序列lable: cout<<"请输入4位待编码消息序列:"<<endl;for(i=0;i<4;i++){cin>>u[i];}//判断是否输入正确数据for(i=0;i<4;i++){if((u[0]==0|u[0]==1)&(u[1]==0|u[1]==1)&(u[2]==0|u[2]==1)&(u[3]==0|u[3]==1)) {cout<<"您所输入的待编码消息序列为:";for(i=0;i<4;i++){cout<<u[i];}cout<<endl;}else{cout<<"输入错误!请输入正确的二进制4位0,1信息序列!"<<endl;goto lable;}}cout<<endl;//输出生成矩阵cout <<"(7,4)汉明码的生成矩阵G为:"<<endl;for(i=0;i<4;i++){for(j=0;j<7;j++)cout <<g[i][j]<< " ";cout << endl;}cout << endl;//编码程序//码字的系统结构分为冗余校验部分和消息部分,结构形式:v(x)={v0,v1,v2,v3,v4,v5,v6} //编码序列中v3,v4,v5,v6均为所提供的消息序列,对于(7,4)汉明码:// v0=v3^v5^v6;// v1=v3^v4^v5;// v2=v4^v5^v6; cout<<" 等待编码中…… "<<endl;cout<<"编码成功!编码后的码字序列为:"<<" ";for(j=0;j<7;j++){if(j==3)v[j]= u[0];if(j==4)v[j]= u[1];if(j==5)v[j]= u[2];if(j==6)v[j]= u[3];if(j==0)v[j]= ((u[0]^u[2])^u[3]); //异或运算if(j==1)v[j]= ((u[0]^u[1])^u[2]); //异或运算if(j==2)v[j]= ((u[1]^u[2])^u[3]); //异或运算cout << v[j] << " ";}cout<<endl;//顺序输入7位待译码有效码字序列loop:int a,result=0;cout<<"请输入7位待译码有效的消息序列:"<<endl;for(i=0;i<7;i++){cin>>v[i];}cout<<endl;for(i=0;i<7;i++){cout<<v[i];}//1.判断是否输入正确0,1序列if((v[0]==0|v[0]==1)&(v[1]==0|v[1]==1)&(v[2]==0|v[2]==1)&(v[3]==0|v[3]==1)&(v[4]==0|v[4]==1)&(v[5]==0|v[5]==1)&(v[6]==0|v[6]==1)){cout<<"输入字码合法"<<endl;}else{cout<<"输入错误!请输入正确的二进制7位0,1码字序列!"<<endl;goto loop;}//2.判断是否为有效码字for(j=0;j<3;j++){a=(v[0]*ht[0][j])^(v[1]*ht[1][j])^(v[2]*ht[2][j])^(v[3]*ht[3][j])^(v[4]*ht[4][j])^(v[5]*ht[5][j])^(v[6]*ht[6][j]);result=result+a;}if(result!=0){cout<<"输入的是无效的字码"<<endl;goto loop;}else cout<<"输入字码有效"<<endl;cout<<"您所输入的待译码的码字序列为:";for(i=0;i<7;i++){cout<<v[i];}cout<<endl;//输出校验矩阵Hcout <<"(7,4)汉明码的校验矩阵H为:"<<endl;for(i=0;i<3;i++){for(j=0;j<7;j++)cout <<h[i][j]<< " ";cout << endl;}cout << endl;//输出校验矩阵HT(这里的T为H 的上标,代表转置),目的是为了利用校正子进行编码检测s=r*HT;cout <<"(7,4)汉明码的校验矩阵H的转置矩阵为:"<<endl;for(i=0;i<7;i++){for(j=0;j<3;j++)cout <<ht[i][j]<< " ";cout << endl;}cout << endl;//检错算法check_table();//查表法cout<<"译码方法二:系统码直接取信息位译码 "<<endl;cout<<" 等待译码中…… "<<endl;cout<<"译码成功!译码后的消息序列为:"<<" ";for(j=0;j<4;j++){if(j==0)u[j]= v[3];if(j==1)u[j]= v[4];if(j==2)u[j]= v[5];if(j==3)u[j]= v[6];cout << u[j] << " ";}cout<<endl;system("pause");return 0;}//查表法函数void check_table(){cout<<"译码方法一:查表法"<<endl;cout<<" k=4,n=7的线性分组码的全部码字 "<<endl;cout<<" 消息码字 | 消息码字"<<endl;cout<<"(0000) (0000000) | (0001) (1010001)"<<endl;cout<<"(1000) (1101000) | (1001) (0111001)"<<endl;cout<<"(0100) (0110100) | (0101) (1100101)"<<endl;cout<<"(1100) (1011100) | (1101) (0001101)"<<endl;cout<<"(0010) (1110010) | (0011) (0100011)"<<endl;cout<<"(1010) (0011010) | (1011) (1001011)"<<endl;cout<<"(0110) (1000110) | (0111) (0010111)"<<endl;cout<<"(1110) (0101110) | (1111) (1111111)"<<endl; }运行结果如下:编码结果为:译码结果为:。