public static int get_crc16 (byte[] bufData, int buflen, byte[] pcrc)
{
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));

            }

}