{
int ret = 0;
int CRC = 0x0000ffff;
int POLYNOMIAL = 0x0000a001;
int i, j;
if (buflen == 0)
{
return ret;
}
for (i = 0; i < buflen; i++)
{
CRC ^= ((int)bufData[i] & 0x000000ff);
for (j = 0; j < 8; j++)
{
if ((CRC & 0x00000001) != 0)
{
CRC >>= 1;
CRC ^= POLYNOMIAL;
}
else
{
CRC >>= 1;
}
}
//System.out.println(Integer.toHexString(CRC));
}
System.out.println(Integer.toHexString(CRC));
pcrc[0] = (byte)(CRC & 0x00ff);
pcrc[1] = (byte)(CRC >> 8);
return ret;
}
/**
* @param args
*/
public static void main(String[] args) {
byte[] aa = {0x30,0x30,0x34,0x36,0x46,0x44,0x36,0x30,0x30,0x30,0x01,0x72,0x65,
0x66,0x65,0x72,0x69,0x6E,0x66,0x6F,0x2E,0x63,0x73,0x76,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x01,(byte)0xf4,0x01};
byte[] bb = new byte[3];
Crc16.get_crc16(aa, aa.length, bb);
System.out.println(Integer.toHexString((int)bb[0] & 0x000000ff));
System.out.println(Integer.toHexString((int)bb[1] & 0x000000ff));
}
/*
* crc校验,输入一个数组,返回一个数组,返回的数组比原数组
* 多了两个字节,也就是两个校验码,低字节在前,高字节在后.
*/
public class CRC16 {
public static int[] crc(int[] data){
int[] temdata=new int[data.length+2];
//unsigned char alen = *aStr – 2; //CRC16只计算前两部分
int xda , xdapoly ;
int i,j, xdabit ;
xda = 0xFFFF ;
xdapoly = 0xA001 ; // (X**16 + X**15 + X**2 + 1)
for(i=0;i<data.length;i++)
{
xda ^= data[i] ;
for(j=0;j<8;j++) {
xdabit =( int )(xda & 0x01) ;
xda >>= 1 ;
if( xdabit==1 )
xda ^= xdapoly ;
}
}
System.arraycopy(data, 0, temdata, 0, data.length);
temdata[temdata.length-2] = (int)(xda & 0xFF) ;
temdata[temdata.length-1] = (int)(xda>>8) ;
return temdata;
}
//这个主函数用来测试用的
public static void main(String args[]){
int[] data={12,25,1,4,10,5,47,2,45,2,3,4,7,5,6,2,45};
int[] d1=crc(data);
for(int i=0;i<d1.length;i++)
System.out.print(d1[i]+" ");
System.out.println();
int[] d2=crc(d1);
for(int i=0;i<d2.length;i++)
System.out.print(d2[i]+" ");
}
}
==================================================================================
下面是C++的算法和参考源代码;
4 校验码
CRC码由发送端计算,放置于发送信息报文的尾部。接收信息的设备再重新计算接收到信息报文的CRC,比较计算得到
的CRC是否与接收到的相符,如果两者不相符,则表明出错。
校验码的计算多项式为(X16 + X15 + X2 + 1)。
具体CRC16码的
计算方法是:
1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;
2.把第一个8位二进制数据 (既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;
3.把CRC寄存器的内容右移一 位(朝低位)用0填补最高位,并检查右移后的移出位;
4.如果移出位为0:重复第3步(再次右移一位);
如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;
5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
8.最后得到的CRC寄存器内容即为:CRC码。
参考算法的C语言实现如下。以下程序
计算一个报文的CRC16并填入报文最后两字节。
void CRC16( unsigned char *aStr ){
unsigned char alen = *aStr – 2; //CRC16只计算前两部分
unsigned int xda , xdapoly ;
unsigned char i,j, xdabit ;
xda = 0xFFFF ;
xdapoly = 0xA001 ; // (X**16 + X**15 + X**2 + 1)
for(i=0;i<alen;i++)
{
xda ^= aStr[i] ;
for(j=0;j<8;j++) {
xdabit =(unsigned char )(xda & 0x01) ;
xda >>= 1 ;
if( xdabit )
xda ^= xdapoly ;
}
}
aStr[alen-2] = (unsigned char)(xda & 0xFF) ;
aStr[alen-1] = (unsigned char)(xda>>8) ;
}
===============================================================================
以代码仅供参考,如有不明白或建议请联系我,共同交流,email:hnbcjzj@163.com
另外提供一个网上找的java crc校验的源程序,我没怎么研究,
import java.io.IOException;
public class CRC16Checker {
private static int[] index = new int[] { 16, 15, 2, 0 };
private static int[] getBinary(String text) {
StringBuffer num = new StringBuffer();
String s; char ch;
for (int i = 0; i < text.length(); i++) { // Change each char to binary code.
s = Integer.toBinaryString(text.charAt(i));
// If the code is less than 8 bit, make it as 8 bit.
for (int j = 8 - s.length(); j > 0; j--) num.append(0);
num.append(s);
}
int len = num.length();
int[] code = new int[len];
for (int i = 0; i < len; i++) // Change each 0/1 char to int.
code[i] = Character.getNumericValue(num.charAt(i));
return code;
}
private static String toHex(int[] num) {
StringBuffer hex = new StringBuffer(num.length / 4);
char[] ch = new char[4];
for (int i = 0; i < num.length;) {
// Change each 0/1 int to char.
ch[0] = Character.forDigit(num[i++], 2);
ch[1] = Character.forDigit(num[i++], 2);
ch[2] = Character.forDigit(num[i++], 2);
ch[3] = Character.forDigit(num[i++], 2);
// Change each 4-bit-code to hex number.
hex.append(Integer.toHexString(Integer.parseInt(String.valueOf(ch), 2)));
}
return hex.toString();
}
// CRC codes main process
public static int[] makeCRCCodes(int[] sourceCodes, int[] multinomial) {
// The lenght of CRC code is N bits longer than source code. The codes
// from 0 to sourceLength are same as the source. N bits after source
// are the CRC codes. N is decided by the multinomial.
// CRC码数组总长为原码长加上校验码码长。数组前部存放原码。校验码存放在数组
// 最后的N位。校验码长度决定于生成多项式数组0位置上的元素。
int sourceLength = sourceCodes.length;
int codesLength = sourceLength + multinomial[0];
int[] crcCodes = new int[codesLength];
// Copy source code from 0 to sourceLength. 拷贝原码。
System.arraycopy(sourceCodes, 0, crcCodes, 0, sourceLength);
int temp, pos;
// Division system. 除法器。
for (int i = 0; i < sourceLength; i++) {
// Count value of the input adding the first register.
// 用第i位原码和第一个寄存器值模二加。
temp = (crcCodes[sourceLength] + sourceCodes[i]) % 2;
// Move registers forwards from (1, length) to (0, length - 1).
// 第二个寄存器及以后的所有寄存器值前移1位。
System.arraycopy(
crcCodes, sourceLength + 1, crcCodes, sourceLength, multinomial[0] - 1);
// Set the last register with counted value.
// 最后一个寄存器值存放计算好的输入值。
crcCodes[codesLength - 1] = temp;
// Count other registers. 按生成多项式的值算出位置,模二加出该寄存器的值。
for (int j = index.length - 2; j > 0; j--) {
pos = codesLength - multinomial[j] - 1;
crcCodes[pos] = (crcCodes[pos] + temp) % 2;
}
}
return crcCodes;
}
public static void main(String[] args) throws IOException {
System.out.print("Input hex data :");
StringBuffer buf = new StringBuffer();
char ch = (char) System.in.read();
while (ch != '/r' && ch != '/n') {
buf.append(ch);
ch = (char) System.in.read();
}
// Get binary codes.
int[] b = CRC16Checker.getBinary(buf.toString());
// Make CRC codes.
b = CRC16Checker.makeCRCCodes(b, CRC16Checker.index);
// Output code as binary number.
for (int i = 0; i < b.length;) {
for (int j = 0; j < 4; j++, i++) System.out.print(b[i]);
System.out.print(' ');
}
System.out.println();
// Output code as hex number.
System.out.println("The CRC16 code is :" + CRC16Checker.toHex(b));
}
}