java中CRC算法是个什么东东

Python012

java中CRC算法是个什么东东,第1张

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 = 7count >=0count--) {

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 = 0k <b.lengthk++)

{

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=0i<b.lengthi++){

for(int j=0j<8j++){

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、首先来看你打java代码:crc=(byte)((crc>>1)^0x8c)和 crc=(byte)(crc>>1)导致这个问题是因为byte的最高位符号位,转换的时候就出错了2、示例代码:package com.testpublic class test {public static void main(String[] args) {byte[] ptr = { 1, 1, 1, 1, 1, 1 }byte res = getCrc(ptr)System.out.println()System.out.println((byte)( (1 >>1) ^ 0x8c ) + ":" +( (1 >>1) ^ 0x8c ) )}public static byte getCrc(byte[] ptr) {int crc = 0for (int i = 0i >1) ^ 0x8c} else {crc = crc >>1}}}return (byte) crc}}

实现方法:最简单的校验就是把原始数据和待比较数据直接进行比较,看是否完全一样这种方法是最安全最准确的。同时也是效率最低的。

应用例子:龙珠cpu在线调试工具bbug.exe。它和龙珠cpu间通讯时,bbug发送一个字节cpu返回收到的字节,bbug确认是刚才发送字节后才继续发送下一个字节的。 实现方法:在数据存储和传输中,字节中额外增加一个比特位,用来检验错误。校验位可以通过数据位异或计算出来。

应用例子:单片机串口通讯有一模式就是8位数据通讯,另加第9位用于放校验值。

bcc异或校验法(block check character)

实现方法:很多基于串口的通讯都用这种既简单又相当准确的方法。它就是把所有数据都和一个指定的初始值(通常是0)异或一次,最后的结果就是校验值,通常把它附在通讯数据的最后一起发送出去。接收方收到数据后自己也计算一次异或和校验值,如果和收到的校验值一致就说明收到的数据是完整的。

校验值计算的代码类似于:

unsigned uCRC=0//校验初始值

for(int i=0i<DataLenthi++) uCRC^=Data[i]

适用范围:适用于大多数要求不高的数据通讯。

应用例子:ic卡接口通讯、很多单片机系统的串口通讯都使用。 (Cyclic Redundancy Check)

实现方法:这是利用除法及余数的原理来进行错误检测的