`
sunguanxing
  • 浏览: 1080907 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java语言实现CRC16算法

阅读更多
由于工作需要,完成上下微机的com口的通讯,所以要用JAVA语言实现CRC16算法,完成通讯后字节流的校验功能。 而在编写数据传输程序时,数据容错是一个非常重要的问题。循环冗余位校验(CycliclRedundncyCheck英文简称CRC)是目前运用非常广泛的一种数据容错方法,在数据传输,数据压缩等领域运用极其广泛。

CRC算法实现有2种方法,一、查表法,二、直接计算,查表法的计算速度相对来说比较快,本人介绍的方法是直接计算法,用了2种方法实现,都是面向对象进行算法的封装。

一、
package com.wms.serial; 

/** 
* @author linduo 
* @version 2006/08/25 
*/ 
public class CRC16{ 
    public int value; 

    public CRC16() 
    { 
     value = 0; 
    } 

    /** update CRC with byte b */ 
    public void update(byte aByte) 
    { 
     int a, b; 

     a = (int) aByte; 
     for (int count = 7; count >=0; count--) { 
         a = a << 1; 
                b = (a >>>8) & 1; 
         if ((value & 0x8000) != 0) { 
      value = ((value << 1) + b) ^ 0x1021; 
         } else { 
      value = (value << 1) + b; 
         } 
     } 
     value = value & 0xffff; 
     return; 
    } 

    /** reset CRC value to 0 */ 
    public void reset() 
    { 
     value = 0; 
    } 
    
    public int getValue() 
    { 
        return value; 
    } 

    public static void main(String[] args) { 
  CRC16 crc16 = new CRC16(); 
  byte[] b = new byte[]{ 
       //(byte) 0xF0,(byte)0xF0,(byte)0xF0,(byte)0x72 
       (byte) 0x2C,(byte)0x00,(byte)0xFF,(byte)0xFE 
       ,(byte) 0xFE,(byte)0x04,(byte)0x00,(byte)0x00 
       ,(byte) 0x00,(byte)0x00 
     }; 
  for (int k = 0; k < b.length; k++) 
  { 
   crc16.update(b[k]); 
  } 
  System.out.println(Integer.toHexString(crc16.getValue())); 
  System.out.println(Integer.toHexString(b.length)); 
} 
} 

二、
package com.wms.serial; 

public class CRC162 { 
public static final void main(String[] args){ 
  CRC162 crc16 = new CRC162(); 
     byte[] b = new byte[]{ 
       //(byte) 0xF0,(byte)0xF0,(byte)0xF0,(byte)0x72 
       (byte) 0x2C,(byte)0x00,(byte)0xFF,(byte)0xFE 
       ,(byte) 0xFE,(byte)0x04,(byte)0x00,(byte)0x00 
       ,(byte) 0x00,(byte)0x00 
     }; 
     System.out.println(Integer.toHexString(crc16.encode(b)));  
     //再把这个2f49替换成b数组的最后两个字节的数组,生成一个新的数组b2 
     byte[] b2 = new byte[]{ 
       //(byte) 0xF0,(byte)0xF0,(byte)0xF0,(byte)0x72 
       (byte) 0x2C,(byte)0x00,(byte)0xFF,(byte)0xFE 
       ,(byte) 0xFE,(byte)0x04,(byte)0x00,(byte)0x00 
       ,(byte) 0x2f,(byte)0x49 
     }; 
     System.out.println(Integer.toHexString(crc16.encode(b2)));   //算出来是 0 
     
     //你可以自已构造一些byte进行加解密试试 
} 

public short encode(byte[] b){ 
     short CRC_x = 0; 
     int pp = 65536; //   1<<16; 
     int pp2 = 69665; // (1<<16) + (1<<12) + (1<<5) + 1 
     for(int i=0;i<b.length;i++){ 
      for(int j=0;j<8;j++){ 
       CRC_x = (short)((CRC_x<<1) + (((b[i]<<j)&0x80)>>7)); 
       if((CRC_x/pp) == 1){ 
        CRC_x=(short)(CRC_x^pp2); 
       } 
      } 
     } 
     return CRC_x; 
} 
} 
分享到:
评论
1 楼 xude1985 2013-04-11  
你经过验证了吗,伙计,为什么我使用两种方法分别对同一字节数组进行加密,得到的CRC是不一样的?晕

相关推荐

Global site tag (gtag.js) - Google Analytics