一、概念
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息
字段和检验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将
结构附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性。
二、计算
我们假设条件如下:
(1)传送的原始消息msg:1,1,0,1,0,0,1,1
(2)给定的生成多项式为gEx:x^4+x+1 即名称为CRC-4
从条件我们可以得到:
根据生成多项式得出生成多项式字码gExCode:1,0,0,1,1
根据生成多项式字码得到校验码码长r=5-1=4
根据原始消息我们得到原始消息表达式为:mEx=x^7+x^6+x^4+x^1+1
因此我们将原始消息向左移动4位:mEx*x^4=x^11+x^10+x^8+x^5+x^4
11 10 9 8 7 6 5 4 3 2 1 0 (多项式的次数)
1 1 0 1 0 0 1 1 0 0 0 0 (得到多项式相关的字码)
从上面的转换(当然也可以从原始消息直接看出)原始消息左移四位后的字码为:110100110000
然后我们用110100110000对生成多项式字码进行模2除法运算:
1 1 0 1 0 0 1 1 0 0 0 0
^
1 0 0 1 1
———————————
0 1 0 0 1 0 1 1 0 0 0 0
^
1 0 0 1 1
————————————
0 0 0 0 1 1 1 0 0 0 0
^
1 0 0 1 1
————————
0 1 1 1 1 0 0
^
1 0 0 1 1
————————
0 1 1 0 1 0
^ 1 0 0 1 1
———————
0 1 0 0 1
所以校验码就是余数:1001
将余数放到原始消息的末尾就构成了最终发送的消息:
1 1 0 1 0 0 1 1 1 0 0 1
接收方拿到这个消息后,将其与生成多项式码进行模2除法,如果余数为0,则发送的消息没有差错;反之,则发送的消息存在差错。
三、错误检测
当接收方收到数据后,用收到的数据对实现约定给定码进行模2除法,若余数为0,则认为数据传输无差错;若
余数不为0,则认为数据传输出现了错误,由于不知道错误发生在什么地方,因此不能进行自动纠正,一般的做法
就是丢弃接收到的数据。
四、Java代码来模拟这个算法
1 public class CRCcheck { 2 public static void main(String[]args) { 3 String code="CRC-4"; 4 if(!generatePolyMap.containsKey(code)) { 5 System.out.println("不存在此编码"); 6 return; 7 } 8 9 int[]gEx=generatePolyMap.get(code); 10 int[] msg=send(new int[]{1,1,0,1,0,0,1,1},gEx); 11 accept(msg,gEx,gEx.length-1); 12 } 13 14 //一些固定的事先约定好的生成多项式 15 final static MapgeneratePolyMap=new HashMap (); 16 static { 17 generatePolyMap.put("CRC-4", new int[]{1,0,0,1,1}); 18 generatePolyMap.put("CRC-8", new int[]{1,0,0,1,1,0,0,0,1}); 19 generatePolyMap.put("CRC-12",new int[]{1,1,0,0,0,0,0,0,0,1,0,1,0,1}); 20 } 21 22 23 public static int[] send(int[] msg,int[] gEx) { 24 //校验码位数 25 int r=gEx.length-1; 26 27 //信息字码长度 28 int k=msg.length; 29 30 //最终发送信息长度,并生成最终放信息的空间 31 int l=r+k; 32 int[] m=new int[l]; 33 34 //初始化新的消息空间 35 for(int i=0;i =0;i--) { 65 m[l-t]=result[i]; 66 t++; 67 } 68 69 System.out.print("发送消息:"); 70 for(int i=0;i