循环码编译码

写前感言

我现在是一名即将毕业的大四本科生,大学生活快要结束了,我整理四年学习资料时发现好多东西都不见了,感觉挺遗憾的,另外自己学过的一些知识由于没有好好记录和整理,导致很混乱,最后我发现自己一直在白嫖,都没有做过什么贡献,使得我下定决心要开始写博客。之前我也有写博客的想法,但由于某些客观原因没有作为,现在想想好像也没什么,只是交流学习,没其他内容。
现在开始我的第一篇博客。

内容

(1)(7,4)循环码的编码
(2)(7,4)循环码的译码
(3)手动测试单个码字编译是否正确
(4)自动测试并计算误比特率

功能模块

(1)计算码多项式次数
(2)利用公式v(x)=xrm(x)+(xrm(x))g(x)编码
(3)伴随式译码
(4)手动测试
(5)自动测试
(6)主函数

结果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码说明

计算码字次数

函数输出num是int型,它的每一位代表一个比特,码字的高位在左,低位在右。函数返回值为次数加一

int highest(int num){//求最高位=次数+1 
	int high=0;
	for(int i=0;i<=6;i++){
		if((num>>i)==1){
			high=i+1;
		}
	}
	return high;
}

功能快捷键

int code(int num){//编码 
	int n_low,n_high;
	n_low=n_high=num<<3;
	//g(x)=00001011
	int g=11;
	while(highest(n_low)>=4) n_low=n_low^(g<<(highest(n_low)-4));
	return (n_high)|n_low;
}

译码

输入为接收码字的十进制表示,输出为译码码字的十进制表示。伴随式译码表中存储的是伴随式对应的第几位错。

int decode(int r){//解码 ,输出信息位 
	//r接收码字 
	int s=r;//s伴随式 
	int v,m; //v译码码字,m信息位 
	int g=11;//g(x)=00001011
	while(highest(s)>=4) s=s^(g<<(highest(s)-4));
	//伴随式译码
	int dict[8]={0,0,1,3,2,6,4,5};//伴随式译码表 
	if(s!=0) v=r^(1<<dict[s]);
	else v=r;
	m=v>>3;//恢复信息位
	return m;
}

手动测试模块

void hand_test(){
	char a,b,c,d;
	cout<<"请输入四位信息元:";
	cin>>a>>b>>c>>d;
	int m=(a-48)*8+(b-48)*4+(c-48)*2+d-48;
	int v=code(m);
	cout<<"编码码字:";
	int b_v[7]={0};
	int times=6;
	while(v!=0){
		b_v[times]=v%2;
		times--;
		v=v/2;
	}
	for(int i=0;i<7;i++){cout<<b_v[i];}
	cout<<endl;
	
	char r1,r2,r3,r4,r5,r6,r7;
	cout<<"请输入接收码字:";
	cin>>r1>>r2>>r3>>r4>>r5>>r6>>r7;
	int r=(r1-48)*64+(r2-48)*32+(r3-48)*16+(r4-48)*8+(r5-48)*4+(r6-48)*2+(r7-48);
	int decode_m=decode(r);
	int decode_bm[4]={0};
	times=3;
	while(decode_m!=0){
		decode_bm[times]=decode_m%2;
		times--;
		decode_m=decode_m/2;
	}
	cout<<"恢复信息位:";
	for(int i=0;i<4;i++){cout<<decode_bm[i];}
	cout<<endl; 
	cout<<"请选择测试模式:手动[1]/自动[2]   ";
}

自动测试模块

double auto_test(int length,float p){
	srand(time(NULL));//随机数种子时变 
	
	if(length%4!=0){
		length=length+4-length%4;
	}
	int len=length;
	int temp;
	int temp_p1=int(p*10000);//1的个数 
	int temp_p0=10000-temp_p1;//0的个数 
	vector<int> lp;//生成转移概率 
	while(temp_p1--){lp.push_back(1);}
	while(temp_p0--){lp.push_back(0);}
	
	vector<int> b,m;//b信息比特流 ,m发送前信息组流
	vector<int> v;//编码码字流 
	vector<int> c,c_group; //c错误比特流,c_grop错误流组 
	vector<int> r;//接收码字流 
	vector<int> decode_m,decode_b;//decode_m译码恢复信息组,b_decode恢复的信息比特流 
	
	/*=================生成比特流,并分组==================*/ 
	while(length--){b.push_back(rand()%2);}
	length=len;//末尾补齐后长度 
	for(int i=0;i<length;i=i+4){
		temp=b[i]*8+b[i+1]*4+b[i+2]*2+b[i+3];
		m.push_back(temp);
	}
	/*=======================编码==========================*/
	for(int i=0;i<m.size();i++){
		v.push_back(code(m[i]));
	}
	/*==============生成信道错误比特流,并分组=============*/
	length=len/4*7;//末尾补齐后长度
	while(length--){c.push_back(lp[rand()%10000]);}
	length=len/4*7;
	for(int i=0;i<length;i=i+7){
		temp=c[i]*64+c[i+1]*32+c[i+2]*16+c[i+3]*8+c[i+4]*4+c[i+5]*2+c[i+6];
		c_group.push_back(temp);
	}
	/*==================经过信道传输======================*/
	for(int i=0;i<v.size();i++){
		r.push_back(v[i]^c_group[i]);
	} 
	/*=============接收译码恢复信息组,和比特流=============*/
	for(int i=0;i<r.size();i++){
		decode_m.push_back(decode(r[i]));
	} 
	for(int i=0;i<decode_m.size();i++){
		temp=decode_m[i];
		int times=3;
		int hash[4]={0}; 
		while(temp!=0){
			hash[times]=temp%2;
			temp=temp/2;
			times--;
		}
		for(int j=0;j<4;j++) decode_b.push_back(hash[j]);
	}
	/*=====================计算误比特率====================*/
	int num_false=0;
	for(int i=0;i<b.size();i++){
		if(b[i]!=decode_b[i]){
			num_false++;
		}
	} 
	double qc;
	qc=num_false*1.0/len;
	return qc;
}

主函数调用

int main(){
	cout<<"请选择测试模式:手动[1]/自动[2]   ";
	int a;
	int length;//length长度 
	float p;//p转移概率 
	double bit_ratio;//自动测试误比特率 
	//=================画图数据==================== 
	vector<double> plt;//画图数据 
	for(int i=0;i<=500;i++){
		p=i*0.001;
		plt.push_back(auto_test(10000,p));
	}
	ofstream fout("result.txt");
	for(int i=0;i<=500;i++){
		fout<<plt[i]<<endl;
	}
	fout.close(); 
	while(scanf("%d",&a)!=EOF){
		cout<<"============================================="<<endl;
		if(a==1) hand_test();
		else{
			cout<<"请确定比特流长度:";cin>>length;
			cout<<"请确定信道转移概率:";cin>>p;
			bit_ratio=auto_test(length,p);
			cout<<"误比特率:"<<bit_ratio;
			cout<<"请选择测试模式:手动[1]/自动[2]   ";
		}
	}
	return 0;
}

完整代码

# include<stdio.h>
# include<vector>
# include<iostream>
# include<stdlib.h> 
#include <time.h>
#include<string>
#include<fstream>
using namespace std;
int highest(int num){//求最高位=次数+1 
	int high=0;
	for(int i=0;i<=6;i++){
		if((num>>i)==1){
			high=i+1;
		}
	}
	return high;
}

int code(int num){//编码 
	int n_low,n_high;
	n_low=n_high=num<<3;
	//g(x)=00001011
	int g=11;
	while(highest(n_low)>=4) n_low=n_low^(g<<(highest(n_low)-4));
	return (n_high)|n_low;
}

int decode(int r){//解码 ,输出信息位 
	//r接收码字 
	int s=r;//s伴随式 
	int v,m; //v译码码字,m信息位 
	int g=11;//g(x)=00001011
	while(highest(s)>=4) s=s^(g<<(highest(s)-4));
	//伴随式译码
	int dict[8]={0,0,1,3,2,6,4,5};//伴随式译码表 
	if(s!=0) v=r^(1<<dict[s]);
	else v=r;
	m=v>>3;//恢复信息位
	return m;
}
void hand_test(){
	char a,b,c,d;
	cout<<"请输入四位信息元:";
	cin>>a>>b>>c>>d;
	int m=(a-48)*8+(b-48)*4+(c-48)*2+d-48;
	int v=code(m);
	cout<<"编码码字:";
	int b_v[7]={0};
	int times=6;
	while(v!=0){
		b_v[times]=v%2;
		times--;
		v=v/2;
	}
	for(int i=0;i<7;i++){cout<<b_v[i];}
	cout<<endl;
	
	char r1,r2,r3,r4,r5,r6,r7;
	cout<<"请输入接收码字:";
	cin>>r1>>r2>>r3>>r4>>r5>>r6>>r7;
	int r=(r1-48)*64+(r2-48)*32+(r3-48)*16+(r4-48)*8+(r5-48)*4+(r6-48)*2+(r7-48);
	int decode_m=decode(r);
	int decode_bm[4]={0};
	times=3;
	while(decode_m!=0){
		decode_bm[times]=decode_m%2;
		times--;
		decode_m=decode_m/2;
	}
	cout<<"恢复信息位:";
	for(int i=0;i<4;i++){cout<<decode_bm[i];}
	cout<<endl; 
	cout<<"请选择测试模式:手动[1]/自动[2]   ";
}

double auto_test(int length,float p){
	srand(time(NULL));//随机数种子时变 
	
	if(length%4!=0){
		length=length+4-length%4;
	}
	int len=length;
	int temp;
	int temp_p1=int(p*10000);//1的个数 
	int temp_p0=10000-temp_p1;//0的个数 
	vector<int> lp;//生成转移概率 
	while(temp_p1--){lp.push_back(1);}
	while(temp_p0--){lp.push_back(0);}
	
	vector<int> b,m;//b信息比特流 ,m发送前信息组流
	vector<int> v;//编码码字流 
	vector<int> c,c_group; //c错误比特流,c_grop错误流组 
	vector<int> r;//接收码字流 
	vector<int> decode_m,decode_b;//decode_m译码恢复信息组,b_decode恢复的信息比特流 
	
	/*=================生成比特流,并分组==================*/ 
	while(length--){b.push_back(rand()%2);}
	length=len;//末尾补齐后长度 
	for(int i=0;i<length;i=i+4){
		temp=b[i]*8+b[i+1]*4+b[i+2]*2+b[i+3];
		m.push_back(temp);
	}
	/*=======================编码==========================*/
	for(int i=0;i<m.size();i++){
		v.push_back(code(m[i]));
	}
	/*==============生成信道错误比特流,并分组=============*/
	length=len/4*7;//末尾补齐后长度
	while(length--){c.push_back(lp[rand()%10000]);}
	length=len/4*7;
	for(int i=0;i<length;i=i+7){
		temp=c[i]*64+c[i+1]*32+c[i+2]*16+c[i+3]*8+c[i+4]*4+c[i+5]*2+c[i+6];
		c_group.push_back(temp);
	}
	/*==================经过信道传输======================*/
	for(int i=0;i<v.size();i++){
		r.push_back(v[i]^c_group[i]);
	} 
	/*=============接收译码恢复信息组,和比特流=============*/
	for(int i=0;i<r.size();i++){
		decode_m.push_back(decode(r[i]));
	} 
	for(int i=0;i<decode_m.size();i++){
		temp=decode_m[i];
		int times=3;
		int hash[4]={0}; 
		while(temp!=0){
			hash[times]=temp%2;
			temp=temp/2;
			times--;
		}
		for(int j=0;j<4;j++) decode_b.push_back(hash[j]);
	}
	/*=====================计算误比特率====================*/
	int num_false=0;
	for(int i=0;i<b.size();i++){
		if(b[i]!=decode_b[i]){
			num_false++;
		}
	} 
	double qc;
	qc=num_false*1.0/len;
	return qc;
}
int main(){
	cout<<"请选择测试模式:手动[1]/自动[2]   ";
	int a;
	int length;//length长度 
	float p;//p转移概率 
	double bit_ratio;//自动测试误比特率 
	//=================画图数据==================== 
	vector<double> plt;//画图数据 
	for(int i=0;i<=500;i++){
		p=i*0.001;
		plt.push_back(auto_test(10000,p));
	}
	ofstream fout("result.txt");
	for(int i=0;i<=500;i++){
		fout<<plt[i]<<endl;
	}
	fout.close(); 
	while(scanf("%d",&a)!=EOF){
		cout<<"============================================="<<endl;
		if(a==1) hand_test();
		else{
			cout<<"请确定比特流长度:";cin>>length;
			cout<<"请确定信道转移概率:";cin>>p;
			bit_ratio=auto_test(length,p);
			cout<<"误比特率:"<<bit_ratio<<endl;
			cout<<"请选择测试模式:手动[1]/自动[2]   ";
		}
	}
	return 0;
}

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值