【Android数据加密与完整性校验之CRC校验】CRC校验貌似对数据量有限制,所以最后选择了MessageDigest类MD5方式验证数据

来源:互联网 发布:大数据应用在哪些行业 编辑:程序博客网 时间:2024/06/16 03:38

转载自:http://blog.csdn.net/qq355667166/article/details/6255243    

 这两天项目中要使用到CRC校验功能,网上大量的例子是针对c、delphi的例子,前期没有做过,理论上也欠缺很多知识,在这里对java如何实现我们想要的crc校验功能做一下自己的总结,以下内容有本分转自网上,希望对有需要的朋友作能够参考一下。

 

一、什么是CRC校验:

     

      CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。

 

   二、CRC的原理若设码字长度为N,信息字段为K位,校验字段为R位(N=K+R),则对于CRC码集中的任一码字,存在且仅存在一个R次多项式g(x),使得

V(x)=A(x)g(x)=xRm(x)+r(x);

其中:    m(x)为K次信息多项式, r(x)为R-1次校验多项式,

         g(x)称为生成多项式:

g(x)=g0+g1x+ g2x2+...+g(R-1)x(R-1)+gRxR

发送方通过指定的g(x)产生CRC码字,接收方则通过该g(x)来验证收到的CRC码字。                                                     

                                      (对于细节性的知识朋友们可以在网上找到大量资料这里不再做重复说明)   (以上来自网络转载)

三、CRC校验码方式有哪些:

 

          1 byte checksum 

          CRC-16    

          CRC-16 (Modbus)  
          CRC-16 (Sick)  
          CRC-CCITT (XModem)  
          CRC-CCITT (0xFFFF)

          CRC-CCITT (0x1D0F)

          CRC-CCITT (Kermit)  
          CRC-DNP          

          CRC-32

 

对于以上方式来说结果可以生成为ASCII、HEX等方式

四、JAVA实现CRC校验

     (1)这里对于CRC-CCITT四种方式进行梳理:

 

        

[java] view plaincopy
  1. public class CRC {  
  2.     /** 
  3.      * CRC-CCITT(Kermit)验证模式 
  4.      * @param str  
  5.      * @return 
  6.      */  
  7.     public String CRC_CCITT_Kermit(String str) {  
  8.         int j, b, rrrc, c, i;  
  9.         String tmpBalance;  
  10.         int k;  
  11.         rrrc = 0;  
  12.         tmpBalance = str;  
  13.         int tmpInt, CharInt;  
  14.         String tmpChar, tmpStr;  
  15.         tmpStr = "";  
  16.         int High;  
  17.         int Low;  
  18.   
  19.     for (j = 1; j <= 3; j++) {  
  20.   
  21.             if (Character.isDigit(tmpBalance.charAt(2 * j - 2))) {  
  22.                 High = Integer.parseInt(tmpBalance.charAt(2 * j - 2) + "");  
  23.   
  24.             } else {  
  25.                 High = 0;  
  26.   
  27.             }  
  28.             if (Character.isDigit(tmpBalance.charAt(2 * j - 1))) {  
  29.                 Low = Integer.parseInt(tmpBalance.charAt(2 * j - 1) + "");  
  30.   
  31.             } else {  
  32.   
  33.                 Low = 0;  
  34.             }  
  35.   
  36.             High = (High & 0xff) << 4;  
  37.   
  38.             High = High | Low;  
  39.   
  40.             k = High;  
  41.   
  42.             for (i = 1; i <= 8; i++) {  
  43.                 c = rrrc & 1;  
  44.                 rrrc = rrrc >> 1;  
  45.                 if ((k & 1) != 0) {  
  46.                     rrrc = rrrc | 0x8000;  
  47.   
  48.                 }  
  49.                 if (c != 0) {  
  50.   
  51.                     rrrc = rrrc ^ 0x8408;  
  52.                 }  
  53.   
  54.                 k = k >> 1;  
  55.             }  
  56.         }  
  57.         for (i = 1; i <= 16; i++) {  
  58.             c = rrrc & 1;  
  59.             rrrc = rrrc >> 1;  
  60.   
  61.             if (c != 0) {  
  62.   
  63.                 rrrc = rrrc ^ 0x8408;  
  64.             }  
  65.   
  66.         }  
  67.         c = rrrc >> 8;  
  68.         b = rrrc << 8;  
  69.         rrrc = c | b;  
  70.         tmpInt = rrrc;  
  71.         tmpStr = "";  
  72.         for (i = 1; i <= 4; i++) {  
  73.             tmpChar = "";  
  74.             CharInt = tmpInt % 16;  
  75.             if (CharInt > 9) {  
  76.                 switch (CharInt) {  
  77.                 case 10:  
  78.                     tmpChar = "A";  
  79.                     break;  
  80.                 case 11:  
  81.   
  82.                     tmpChar = "B";  
  83.                     break;  
  84.                 case 12:  
  85.                     tmpChar = "C";  
  86.                     break;  
  87.   
  88.                 case 13:  
  89.   
  90.                     tmpChar = "D";  
  91.                     break;  
  92.   
  93.                 case 14:  
  94.   
  95.                     tmpChar = "E";  
  96.                     break;  
  97.   
  98.                 case 15:  
  99.   
  100.                     tmpChar = "F";  
  101.                     break;  
  102.   
  103.                 }  
  104.             } else {  
  105.   
  106.                 tmpChar = Integer.toString(CharInt);  
  107.             }  
  108.   
  109.             tmpInt = tmpInt / 16;  
  110.             tmpStr = tmpChar + tmpStr;  
  111.   
  112.         }  
  113.   
  114.         System.out.println("tmpStr:" + tmpStr);  
  115.   
  116.         return tmpStr;  
  117.   
  118.     }  
  119.       
  120.     /** 
  121.      * CRC-CCITT(XModem) 
  122.      * CRC-CCITT(0xFFFF)   
  123.      * CRC-CCITT(0x1D0F)  
  124.      * 校验模式 
  125.      * @param flag< XModem(flag=1) 0xFFFF(flag=2) 0x1D0F(flag=3)> 
  126.      * @param str 
  127.      * @return 
  128.      */  
  129.     public String  CRC_CCITT( int flag,String str) {   
  130.         int crc = 0x00;          // initial value  
  131.         int polynomial = 0x1021;     
  132.         byte[] bytes=str.getBytes();  
  133.           
  134.         switch(flag){  
  135.         case 1:  
  136.             crc=0x00;  
  137.             break;  
  138.         case 2:  
  139.             crc=0xFFFF;  
  140.             break;  
  141.         case 3:  
  142.             crc=0x1D0F;  
  143.             break;  
  144.           
  145.         }  
  146.         for (int index = 0 ; index< bytes.length; index++) {  
  147.             byte b = bytes[index];  
  148.             for (int i = 0; i < 8; i++) {  
  149.                 boolean bit = ((b   >> (7-i) & 1) == 1);  
  150.                 boolean c15 = ((crc >> 15    & 1) == 1);  
  151.                 crc <<= 1;  
  152.                 if (c15 ^ bit) crc ^= polynomial;  
  153.              }  
  154.         }  
  155.         crc &= 0xffff;  
  156.         str = Integer.toHexString(crc);  
  157.         return str;  
  158.           
  159.     }  

0 0