CRC校验码的理解+CRC校验码算法代码

CRC即循环冗余校验(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。(以上摘自百度百科)


CRC校验码的计算过程:

1,先约定一个校验码。这里有个个人理解:校验码与生成多项式的关系:校验码=生成多项式右移一位

常见的CRC生成多项式码有:
crc_4:10011
crc_8:100110001
crc_16:11000000000000101

2,将信息码左移校验码长度个单位,即在信息码后面补N-1个0 ,N为多项式长度(注意这两种表示方法)

3,将补0的信息码与多项式码进行异或运算 额,具体点吧:

(1)先将信息码与多项式码高位对齐,进行异或运算

(2)上一步得到的余数的首位如果为0左移一位,为1就转到(1)

(3)重复以上两步,直到余数的长度为校验码的长度

(4)得到的就是CRC校验码


当然,这只是理论上的计算方法,更不是CRC校验码的原理,CRC校验码的原理是多项式的各种操作~这里就不多讲了,网上资料很多

那么用JAVA程序来实现这个过程就有点麻烦了,为了直观,我用整型数组来装01信号与多项式码,为此我定义了异或操作,左右移操作,补0操作。具体见代码注脚。

(本人水平有限,欢迎指正)
//说明:本代码可以实现任何01信号串的CRC校验码的计算
//只需输入待定信号与约定的多项式码即可得到CRC校验码
//常见的CRC多项式码有:
//crc_4:10011
//crc_8:100110001
//crc_16:11000000000000101
import java.util.Scanner;

public class MyCrc {
	public static void main(String args[]) {
		System.out.println("输入信号:(如1100100):");
		int a[]=jieShou();                            //将输入的数字串用整型数组接收
		System.out.println("输入多项式码:(如1011):");
		int g[]=jieShou();                            //接收多项式码
		int glength=g.length-1;                       //多项式码-1=校验码长度
		a=jiaWei(a, glength);                         //给信息码后面补校验码长度个0
		g=jiaWei(g, a.length-g.length);               //给多项式码长度补0,让其长度=补0后的信息码
		
//////////进行CRC的计算////////////
		while (a.length>glength) {                    //直到a的长度等于校验码的长度(就是要附加的校验码长度)
			if (a[0]==0) {                            //首端是否为0
				a=zuoYi(a);                           //左移
				g=youYi(g);                           //多项式码右移
			}
			else {
				a=yiHuo(a, g);	               	      //异或
			}
		}
		
		System.out.println("校验码为:");
		show(a);     
	}
	
public static int[] jieShou() {                       //接收01字符串并转存成整型数组
		String s;
		Scanner d=new Scanner(System.in);
		s=d.next();
		char[] q=s.toCharArray();
		int temp[]=new int[q.length];
		for (int j = 0; j < q.length; j++) {
			temp[j]= Integer.parseInt(String.valueOf(q[j]));;
		}
		return temp;
	}
	
public static int[] yiHuo(int[] a,int[] b) {          //异或操作
		int temp[]=new int[a.length];
		for (int j = 0; j < a.length; j++) {
			if (a[j]-b[j]<0) {
				temp[j]=b[j]-a[j];
			}
			else {
				temp[j]=a[j]-b[j];
			}
		}
		return temp;
	}
	
	public static int[] jiaWei(int[] a,int b) {        //补0操作
		int temp[]=new int[a.length+b];
		for (int i = 0; i < a.length; i++) {
			temp[i]=a[i];
		}
		return temp;	
	}
	
	public static int[] zuoYi(int[] a) {              //左移操作
		int temp[]=new int[a.length-1];
	    for(int i=0;i0;i--){                //依次向后赋值
	        a[i] = a[i-1]; }
		for (int i = 0; i < temp.length; i++) {       //去尾
			temp[i]=a[i+1];
		}
		return temp;
		}

	public static void show(int[] a) {                //打印
			for (int i = 0; i < a.length; i++) {
				System.out.print(a[i]);
			}
			System.out.print("\n");
		}
}

CRC的校验原理  

最详细易懂的CRC-16校验原理


向程序员致敬




你可能感兴趣的:(STM32)