java CRC16校验,原版C++,改编成java

 
/*
 * 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  {        
  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   System.out.print(d1[i]+" ");
  System.out.println();
  int[] d2=crc(d1);
  for(int i=0;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{        
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:[email protected]

另外提供一个网上找的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));
            }
}

你可能感兴趣的:(java CRC16校验,原版C++,改编成java)