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