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;i<a.length-1;i++){ //依次向前赋值
a[i] = a[i+1];}
for (int i = 0; i < temp.length; i++) { //去尾
temp[i]=a[i];
}
return temp;
}
public static int[] youYi(int[] a) { //右移操作
int temp[]=new int[a.length-1];
for(int i=a.length-1;i>0;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校验原理
向程序员致敬