今天上完离散课,老师上课讲解了线性分组码
通过陪集的思路,我算是大致理解了线性分组码的原理
因为目前只会了[7:4]线性分组码,其他更高数据量的线性分组码需要线性代数的知识,而且有些晦涩难懂,我就没仔细看
本文主要目的是通过哈希+位运算成功实现[7:4]线性分组码的纠错功能
首先我们来介绍一下[7:4]线性分组码,前4位是有效数字位,后三位是校验位
首先定义7维向量群
G={x1x2x3x4x5x6x7}为一个字串,群的运算为模2加法
前四位使我们传递信息的信息位,后三位的运算规则是
x5=x1+x2+x3(模2加法)
x6=x1+x2+x4
x7=x1+x3+x4
后三位作为一个校验单元用来判断我们的(是校验单元的原因是这三位是随着前四位变化的,一旦前四位出现错误,后三位的逆运算可以判断是哪里出现的错误)
其实本人的理解在这里,线性分组码是将错误码最小还原为最接近的源码,但是这里有可能还有错误的出现,一旦多次出现错误的话,显然我们还是有将其判断为正确的可能性,但是在这里我们不考虑这种可能性
在实际的实现中:
1.数据结构:
哈希表将所有的分组码经过哈希映射到一个标记地址(标记地址的含义是最相近的源码的存储的位置)
再开辟一个一维的16个码字的源码类数组
2.通过位运算将压缩的unsigned变量不断更新,也就会说我在实现的过程中为了节约内存利用unsigned char变量压缩存储在一个字节以内
Code:
#include"iostream"
#include"cstdio"
#include"cstring"
#define GETPOS(x,y,k) k=((1<<y)&x)>>y
#define PUTPOS(x,y) x=((1<<y)|x)
using namespace std;
int hashmap[130]; //建立哈希映射
class point
{
public:
point()
{
data='\0';
}
point(char k[])
{
data='\0';
for(int i=0;i<=6;i++) if(k[i]!='0') PUTPOS(data,6-i);
}
inline void set(int x)
{
data='\0';
data=(unsigned char)x;
data<<=3; //右移运算三位,有效位,空余校验位
}
inline void setfalse(int x)
{
data='\0';
data=(unsigned char)x;
}
void creatafter()
{
//x5校验位
int a=0;
int b=0;
int c=0;
GETPOS(data,6,a);
GETPOS(data,5,b);
GETPOS(data,4,c);
if((a+b+c)%2!=0) PUTPOS(data,2);
//x6校验位
GETPOS(data,3,c);
if((a+b+c)%2!=0) PUTPOS(data,1);
//x7校验位
GETPOS(data,4,b);
if((a+b+c)%2!=0) PUTPOS(data,0);
}
point operator+(point b)
{
point k;
k.data=data^b.data;
return k;
}
int returndata()
{
return (int)data;
}
friend ostream& operator<<(ostream& out,point& x)
{
int h=0;
for(int i=6;i>=0;i--)
{
GETPOS(x.data,i,h);
if(h!=0) printf("1");
else printf("0");
}
return out;
}
private:
unsigned char data;
};
int main()
{
point map[16];
for(int i=0;i<16;i++) map[i].set(i),map[i].creatafter(); //生成16个线性分组码
//建立正确映射
for(int i=0;i<16;i++) hashmap[map[i].returndata()]=-1;
for(int i=0;i<7;i++) //建立映错误射
{
for(int j=0;j<16;j++)
{
point k;
k.setfalse(1<<i);
k=k+map[j];
hashmap[k.returndata()]=j;
}
}
char number[8];
memset(number,0,sizeof(number));
while(1)
{
memset(number,0,sizeof(number));
scanf("%s",number);
point h(number); //重载的构造函数
int p=h.returndata();
if(hashmap[p]==-1)
{
cout<<"译码结果显示没有错误出现"<<endl;
cout<<"译码是:";
cout<<h<<endl;
}
else
{
cout<<"译码结果显示出现传输错误"<<endl;
cout<<"源代码是:";cout<<h<<endl;
cout<<"纠错码是:";cout<<map[hashmap[p]]<<endl;
}
}
return 0;
}