循环冗余校验码(CRC)代码

介绍

  1. 产生式为: G(x) = 1 * x 4 x^4 x4 + 0 * x 3 x^3 x3 + 0 * x 2 x^2 x2 + 1 * x 1 x^1 x1 + 1 * x 0 x^0 x0 => 10011
  2. 数据为:1100001110
  3. 计算过程:
    在这里插入图片描述
  4. CRC检测,用得到的数据帧除以生成式 “ 10011 ”,如果余数为0,则正确,否则错误。

代码

#include<bits/stdc++.h> 
using namespace std; 

class CRC {
	public:	
		
	void print_16(int sum)//输出对应的十六进制值 
	{
		if(sum<9) cout<<sum;
		else if(sum == 10) cout<<"A";
		else if(sum == 11) cout<<"B";
		else if(sum == 12) cout<<"C";
		else if(sum == 13) cout<<"D";
		else if(sum == 14) cout<<"E";
		else if(sum == 15) cout<<"F";
	}
	void print_result_16(int code_result[],int len) //按十六进制转换 
	{ 
		int remain = len % 4 ;
		int sum = 0;
		int power = 0;
		for(int i = remain - 1 ; i >= 0 ; i-- ) 
		{
			sum += code_result[i]*pow(2,power++);
		} 
	 	print_16(sum);
		for(int i=0;i<len/4;i++)
		{
			sum = 0; power = 0;
			for(int j = remain+i*4+4-1;j >= remain+i*4;j--)
			{
				sum += code_result[j]*pow(2,power++);;
			}
			print_16(sum);
		}
	}
	void code()
	{
		char s[100];
		cout<<"输入要转化为CRC的二进制串:"<<endl; 
		cin>>s; 
		int N = strlen(s);  //待编码的串 
		int  x[6]={1,1,0,1,0,1};//指定的生成式 
		int  a[100][21]={0};//定义了二维数组 
		for(int i=0;i<N;i++)      
			a[0][i]=(int)s[i]-48;     
		for(int i=0; i< N ;i++)     //开始计算
		{
			a[i][i+5]=a[0][i+5];
			for(int j=0;j<=5;j++)   
			{
				if(a[i][i]==0) x[0]=x[1]=x[2]=x[3]=x[4]=x[5]=0;   //若开头为0,则除数置0,免去移位  
				if(a[i][i+j]==x[j]) a[i+1][i+j]=0;                  //相同时赋值0
					else a[i+1][i+j]=1;                                 //不同时赋值1
			}
			x[0]=1,x[1]=1,x[2]=0,x[3]=1,x[4]=0,x[5]=1;           //还原 110101除数
		}
		int code_result[100];//编码后的结果保存  
		int count = 0; //结果下标 
		cout<<"CRC编码二进制: ";
		for(int i=0;i<N;i++)  
		{
			code_result[count++] = a[0][i];         //输出原来的十六位码
			printf("%d",a[0][i]);                 
		}
		for(int i=0;i<5;i++)                     //余数 
		{
			code_result[count++] = a[N][i+N];
			printf("%d",a[N][i+N]);
		}
		printf("\n");
		cout<<"CRC编码十六进制: ";  
	 	print_result_16(code_result,count);
	 	cout<<endl;
	} 
	void check_code()
	{
		char s[100];
		cout<<"输入要验证的二进制串:"<<endl; 
		cin>>s; 
		int N = strlen(s);  //待编码的串 
		int  x[6]={1,1,0,1,0,1};//指定的生成式 
		int  a[100][21]={0};// 保存余数 
		for(int i=0;i<N;i++)            //输入数字 
			a[0][i]=(int)s[i]-48;     
		for(int i=0; i< N ;i++)     
		{
			a[i][i+5]=a[0][i+5];
			for(int j=0;j<=5;j++)     
			{
				if(a[i][i]==0) x[0]=x[1]=x[2]=x[3]=x[4]=x[5]=0;   //若开头为0,则除数置0,免去移位 
				if(a[i][i+j]==x[j]) a[i+1][i+j]=0;                 //相同时赋值0
					else a[i+1][i+j]=1;                                 //不同时赋值1
			}
			x[0]=1,x[1]=1,x[2]=0,x[3]=1,x[4]=0,x[5]=1;          //还原 110101除数
		}
		int code_result[100];//编码后的结果保存  
		int count = 0; //结果下标 
		cout<<"其余数为:";
		for(int i=0;i<5;i++)                     //余数 
		{
			code_result[count++] = a[N][i+N];
			printf("%d",a[N][i+N]);
		} 
		cout<<endl;
		int sum = 0;
		int power = 0;
		for(int i = count-1 ; i >= 0 ; i-- ) 
		{
			sum += code_result[i]*pow(2,power++);
		} 
		if(sum == 0) cout<<"通过CRC验证"<<endl;
		else  
			cout<<"CRC编码出现错误"<<endl; 
	}
};
 
int main()
{
	CRC crc; //创建crc类 
	cout<<"开始程序"<<endl;
	while(true)
	{
		cout<<"****************************************************************"<<endl; 
		cout<<"生成CRC编码输入0,  检验CRC编码输入1,  退出程序输入2:"<<endl;
		int choose ;
		cin>>choose;
		switch(choose)
	    {
	        case 0: crc.code(); break;//生成发送的CRC编码
	        case 1: crc.check_code ();break;//检验CRC编码  
	        case 2: return 0;
	    } 
	 } 
	return 0;                   
}
/*
测试样例: 
开始程序
****************************************************************
生成CRC编码输入0,  检验CRC编码输入1,  退出程序输入2:
0
输入要转化为CRC的二进制串:
1010001101
CRC编码二进制: 101000110101110
CRC编码十六进制: 51AE
****************************************************************
生成CRC编码输入0,  检验CRC编码输入1,  退出程序输入2:
1
输入要验证的二进制串:
101000110101110
其余数为:00000
通过CRC验证
****************************************************************
生成CRC编码输入0,  检验CRC编码输入1,  退出程序输入2:
1
输入要验证的二进制串:
101000110101111
其余数为:10101
CRC编码出现错误
****************************************************************
生成CRC编码输入0,  检验CRC编码输入1,  退出程序输入2:
2
*/ 

运行结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值