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<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));
            }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Java CRC16校验算法是一种常用的校验算法,用于检测数据传输或存储中的错误。CRC16算法生一个16位的循环冗余校验码,用于验证数据完整性。 CRC (Cyclic Redundancy Check) 是一种循环冗余校验技术,通过多项式除法运算来生校验码。CRC16是其中的一种算法,它使用16位的校验码。 Java中实现CRC16校验算法可以使用位操作和位移运算,步骤如下: 1. 创建一个初始值为0的16位整数变量crc。 2. 遍历待校验的数据,对每个字节进行处理。 3. 将当前字节和crc的低8位进行异或操作,并将结果存回crc。 4. 循环8次,每次右移1位,并检查最低位是否为1。 - 如果最低位为1,则将crc与0xA001进行异或操作。 - 如果最低位为0,则不进行异或操作。 5. 重复第2步至第4步,直到处理完所有字节。 6. 返回最终得到的crc结果,即为校验码。 Java中实现CRC16校验算法的代码示例: ```java public static int calculateCRC16(byte[] data) { int crc = 0x0000; for (byte b : data) { crc ^= (int) b & 0xFF; for (int i = 0; i < 8; i++) { if ((crc & 0x0001) != 0) { crc = (crc >> 1) ^ 0xA001; } else { crc >>= 1; } } } return crc; } ``` 以上就是Java CRC16校验算法的简要介绍和实现示例,通过这个算法可以有效地检测数据传输或存储中的错误。 ### 回答2: CRC16是一种校验算法,用于对数据进行校验和验证。它通过将数据转化二进制位,并进行多项式取模运算来计算校验和。 CRC16算法的运算步骤如下: 1. 初始化校验值为0xFFFF。 2. 将待校验的数据按位转换为二进制形式。 3. 从高位开始,依次进行以下操作: - 将校验值与当前位异或。 - 如果结果的最高位为1,则将结果与一个预设的固定数值0x1021异或,否则什么都不做。 - 将结果左移一位。 4. 重复第3步,直到所有位都处理完毕。 5. 最后,将校验值取反,得到最终的校验和。 例如,假设待校验的数据为0xA1B2C3D4E5F6,将其转换为二进制形式为101000011011001011000011110100111011010111100110。 根据CRC16算法进行计算,最终得到的校验和为0xEA4D。 CRC16校验算法在网络通信、数据传输等领域中被广泛应用。其优点是计算速度快、实现简单,并且在数据传输过程中可以检测出大部分的传输错误。但需要注意的是,CRC16算法并不能保证100%的可靠性,只能对错误进行检测和部分纠正。 在Java中,可以使用现有的CRC16库来进行CRC16校验的计算。也可以自己实现该算法,通过位运算和异或操作来完校验和的计算。 ### 回答3: CRC16是一种校验算法,用于检测数据传输过程中的错误。它通过对数据进行计算,生一个16位的校验码。CRC16算法是广泛应用于通信领域的一种校验方式。 CRC16算法的原理比较简单,主要通过多项式除法来实现。首先,将需要进行校验的数据按照特定的规则来生一个二进制串,然后通过不断地进行异或和右移操作,最终得到一个16位的校验码。 具体实现CRC16算法的过程如下: 1. 初始化一个16位的寄存器为FFFFH,即所有位都为1。 2. 将待校验的数据按位进行异或操作,并将结果与寄存器进行异或。 3. 对寄存器进行右移一位,丢弃最低位,如果最低位为1,则与一个特定的多项式0xA001进行异或。 4. 重复2和3步骤,直到所有数据位都经过了异或操作。 5. 最后,得到的16位寄存器的内容就是CRC16校验码。 CRC16算法具有较高的校验能力和良好的检错性能,因此在通信中被广泛应用。它可以有效地检测数据传输中的错误,保证数据的完整性和正确性。 总的来说,CRC16是一种简单且高效的校验算法,适用于各种数据校验的场景。在Java中,可以通过使用位运算和逻辑运算等操作来实现CRC16算法的计算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值