哈希+位运算实现差错控制编码([7:4]线性分组码-离散数学)

今天上完离散课,老师上课讲解了线性分组码

通过陪集的思路,我算是大致理解了线性分组码的原理

因为目前只会了[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;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值