📄 unit1.~cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <iostream.h>
#include <cassert.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <cmath.h>
#include <math.hpp>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
unsigned long CRC32 = 0x00000000L;//设变量存放CRC32校验值
const unsigned long GenPolynomial = 0x04c11db7L; // 使用降序生成多项式
void bitByBit(bool bit);
void bitCRC(bool bit);
int main(int argc, char* argv[])
{
unsigned int err_1bit=0; //单比特错误计数器
unsigned int err_2bit=0; //双比特错误计数器
unsigned int err_none=0; //无错误传输计数器
unsigned int loop; //循环测试计数器
unsigned int loop_num; //循环测试次数
cout<<"请输入循环测试的次数:"<<endl<<endl;
cin>>loop_num;
for (loop=0;loop<loop_num;loop++)
{//为了对CRC32纠错进行测试,设定此循环,对同一经CRC32编码信息进行信道模
//拟,也可设定、查看信道特性
/*发送端起始*/
unsigned int MsgLength,OrgLength,Shift;// 信息长度,原始消息长度,移位
bool multi_err=true; //多比特错误标签,默认true
unsigned short int data[]={0xaaaa,0xcc2b,0xb23c,0x12c3,0x142f,0xcfab,
0x14ff,0xfc13,0xfaf4}; //待发送的原始数据消息
OrgLength=sizeof(data)/sizeof(unsigned short int);//原始消息长度
cout<<endl;
cout<<"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl<<endl;
cout<<"待发送消息:"<<endl;
for (unsigned int i=0;i<OrgLength;i++)
{cout<<hex<<data[i]<<" ";
}
cout<<endl;
cout<<endl;
unsigned short int *SampleMsg;
SampleMsg=(unsigned short int *)malloc(sizeof(unsigned short int)*(OrgLength+2));
memset(SampleMsg,0,sizeof(SampleMsg));
for (unsigned int n=0;n<OrgLength;n ++)
{SampleMsg[n]=data[n];
}
SampleMsg[OrgLength]=0x0000; //将原始消息赋值给待发送信息,末尾补32位0
SampleMsg[OrgLength+1]=0x0000;
MsgLength=OrgLength+2; //补0后的待发送信息长度
CRC32=0;
for(unsigned int i = 0;i<MsgLength;++i)
{//对数组内每个元素按位进行CRC,计算出补0后消息的CRC校验值
unsigned short int ch = SampleMsg[i]; //校验运算,即16位一组除以生成多
unsigned short int mask = 0x8000; //项式,求得CRC32即为余数,也就
for (int j = 0; j < 16; ++j) //是校验值
{
bitCRC(ch & mask);//按字进行校验运算
mask >>= 1;
}
}
cout<<endl<<endl<<"计算补0消息CRC校验值 :0x"<<hex<<CRC32; //显示最终校验值
cout<<endl<<endl;
Shift = 32;
for (int k = 0; k < 2; ++k)
{//在原始信息位后加上32位的校验值,也就是4个字节校验信息
Shift -= 16;
SampleMsg[OrgLength + k] = static_cast<unsigned short int> (CRC32 >> Shift);
}
CRC32 = 0;
cout<<"待发送的信息 (实际消息 + CRC) : ";
for(unsigned int i = 0;i<MsgLength;++i)
{//追加校验信息后的数据
cout<<hex<<SampleMsg[i]<<" ";
}
cout<<endl;
/*以下只是验证CRC32原理,加CRC32值后的信息CRC校验为0,本身不是编码部分*/
for(unsigned int l = 0;l<MsgLength;++l)
{//对追加校验信息后的消息进行校验
unsigned short int ch = SampleMsg[l]; //按字校验,求得的余数就是CRC32
unsigned short int mask = 0x8000; //值,此时应该为0
for (int m = 0; m < 16; ++m)
{
bitCRC(ch & mask);
mask >>= 1;
}
}
cout<<endl<<endl<<"待发送信息的CRC校验(应为0) :0x"<<hex<<CRC32;
cout<<endl<<endl; //对追加校验信息的待发送信息再进行CRC校验运算验证
/*以上只是验证CRC32原理,加CRC32值后的信息CRC校验为0,本身不是编码部分*/
unsigned long int *ErrTable; //错误图样 存储不同错误下的CRC值
unsigned long int *ErrCrecTable;//纠错图样,纠正单个比特错误的表
unsigned short int *ErrTableCrt;
ErrTable=(unsigned long int *)malloc(sizeof(unsigned long int)*(MsgLength*16));
memset(ErrTable,0,sizeof(ErrTable));
ErrCrecTable=(unsigned long int *)malloc(sizeof(unsigned long int)*(MsgLength*16));
memset(ErrCrecTable,0,sizeof(ErrCrecTable));
ErrTableCrt=(unsigned short int *)malloc(sizeof(unsigned short int)*(MsgLength));
memset(ErrTableCrt,0,sizeof(ErrTableCrt));
for (unsigned int i=0;i<MsgLength;i++) //生成校验图样
{
unsigned short int window=0x8000;
for (int j=0;j<16;j++)
{
for (unsigned int k=0;k<MsgLength;k++)
{ErrTableCrt[k]=SampleMsg[k];
}
ErrTableCrt[i]= ErrTableCrt[i]^window;
CRC32 = 0;
for(unsigned int l = 0;l<MsgLength;++l) //对数组内每个元素按位进行CRC
{unsigned short int ch = ErrTableCrt[l]; //校验运算,即16位一组除以生成多
unsigned short int mask = 0x8000; //项式,求得CRC32即为余数,也就
for (int n = 0; n < 16; ++n) //是校验值
{bitCRC(ch & mask);//按字进行校验运算
mask >>= 1;
}
}
ErrTable[i*16+j]=CRC32;
ErrCrecTable[i*16+j]=window;
window>>=1;
}
}
/*发送端终止*/
/*信道起始*/
cout<<endl<<endl;
cout<<"经过信道传输后......"<<endl;
cout<<endl;
cout<<"*************************************************************"<<endl;
cout<<endl;
int temp; //生成0-1分布,模拟50%误码
srand((unsigned int)GetTickCount());
temp=rand()%100;
int bina=temp-int(temp/2)*2;
if (bina==1){
double g=RandG(10,1);
if (8<=g&&12>=g){ //用高斯分布生成单、双比特错误
int p,q;
srand((unsigned int)GetTickCount());
p=rand()%(MsgLength-1);
q=rand()%15;
SampleMsg[p]=SampleMsg[p]^ErrCrecTable[p*16+q];
//信道干扰,加入单比特随机干扰
err_1bit++;
cout<<endl;
cout<<"发生单比特错误!"<<endl;
cout<<endl<<endl;
}else
{int p,q,m,n;
srand((unsigned int)GetTickCount());
p=rand()%(MsgLength-1);
q=rand()%15;
Sleep(10);
m=rand()%(MsgLength-1);
n=rand()%15;
SampleMsg[p]=SampleMsg[p]^ErrCrecTable[p*16+q];
SampleMsg[m]=SampleMsg[m]^ErrCrecTable[m*16+n];
//信道干扰,加入双比特随机干扰
err_2bit++;
cout<<endl;
cout<<"发生双比特错误!"<<endl;
cout<<endl<<endl;
}
}else
{err_none++;
cout<<endl;
cout<<"无错误传输……"<<endl;
cout<<endl<<endl;
}
cout<<"*************************************************************"<<endl;
cout<<endl<<endl;
cout<<endl<<endl;
/*信道终止*/
/*接收端起始*/
cout<<"接收到的信息 (接收到的消息 + CRC) : ";
for(unsigned int i = 0;i<MsgLength;++i)
{//经过信道传输后的信息
cout<<hex<<SampleMsg[i]<<" ";
}
cout<<endl;
CRC32 = 0;
for(unsigned int l = 0;l<MsgLength;++l)
{//对收到的信息进行校验
unsigned short int ch = SampleMsg[l]; //按字校验,求得的余数就是CRC32
unsigned short int mask = 0x8000; //值,若无误码,则此值应该为0
for (int m = 0; m < 16; ++m)
{
bitCRC(ch & mask);
mask >>= 1;
}
}
cout<<endl<<endl<<"接收到信息的CRC校验 :0x"<<hex<<CRC32;
cout<<endl<<endl; //此时的CRC32就是检验误码与否的值
if (CRC32==0x0){
multi_err=false;
cout<<"信息无错误传输!"<<endl<<endl<<endl;
cout<<"经过CRC32校验后的原始消息"<<endl;
for(unsigned int i=0;i<MsgLength-2;i++)
{
cout<<SampleMsg[i]<<" ";
}
cout<<endl;
}else
{
for(int i=0;i<9+2;i++)
{ for(int j=0;j<16;j++)
{ if(CRC32==ErrTable[i*16+j])
{multi_err=false;
SampleMsg[i]^=ErrCrecTable[i*16+j];
cout<<"第"<<dec<<i<<"字块第"<<dec<<j<<"位出错,已纠正"<<endl;
}
}
}
CRC32 = 0;
for(unsigned int l = 0;l<MsgLength;++l)
{//对收到的消息在校验后再通过计算CRC值进行验证
unsigned short int ch = SampleMsg[l];//按字校验,求得的余数就是CRC32
unsigned short int mask = 0x8000; //值,若无误码,则此值应该为0
for (int m = 0; m < 16; ++m)
{
bitCRC(ch & mask);
mask >>= 1;
}
}
cout<<"经过纠错后信息的CRC32值(应为0) 0x: "<<hex<<CRC32<<endl;
cout<<endl<<endl;
cout<<"经过CRC32校验后的消息"<<endl;
for(unsigned int i=0;i<MsgLength-2;i++)
{
cout<<SampleMsg[i]<<" ";
}
cout<<endl<<endl;
}
if(multi_err==true){//若不是单比特错误或者无错,则无法纠正
cout<<endl;
cout<<"非单比特错误,无法纠正!"<<endl<<endl<<endl;
}
free(SampleMsg);
free(ErrTable);
free(ErrCrecTable);
free(ErrTableCrt);
/*接收端终止*/
}
cout<<endl<<endl<<endl;
cout<<"共进行了"<<dec<<loop_num<<"次传输测试"<<endl;
cout<<"共发生"<<dec<<err_1bit<<"次单比特错误,占"<<(double)err_1bit/loop_num*100<<"%"<<endl;
cout<<"共发生"<<dec<<err_2bit<<"次双比特错误,占"<<(double)err_2bit/loop_num*100<<"%"<<endl;
cout<<"共发生"<<dec<<err_none<<"次无错传输,占"<<(double)err_none/loop_num*100<<"%"<<endl;
getch();
return 0;
}
//---------------------------------------------------------------------------
void bitByBit(bool bit)
{
cout<<bit;
bool firstBit = (CRC32 & 0x80000000L);
CRC32 = CRC32 << 1;
CRC32 = CRC32^bit;
if (firstBit)
{
CRC32 = CRC32 ^ GenPolynomial;
}
}
void bitCRC(bool bit)
{
bool firstBit = (CRC32 & 0x80000000L);
CRC32 = CRC32 << 1;
CRC32 = CRC32^bit;
if (firstBit)
{
CRC32 = CRC32 ^ GenPolynomial;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -