⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.~cpp

📁 这是一个CRC32位的校验程序
💻 ~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 + -