使用字节数组计算JAVA中的CRC

时间:2014-01-14 07:11:08

标签: java arrays char hex byte

我已将CRC功能更改为采用字节数组。 CRC功能如下:

    public class CalculateCRCByte
    {
      /* Table of CRC values for high–order byte */
      static byte auchCRCHi[] = {
        (byte)0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,
        (byte)0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,
        (byte)0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,
        (byte)0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,
        (byte)0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,
        (byte)0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,
        (byte)0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,
        (byte)0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,
        (byte)0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,
        (byte)0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,
        (byte)0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,
        (byte)0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,
        (byte)0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,
        (byte)0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,
        (byte)0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,
        (byte)0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,
        (byte)0x00,(byte) 0xC1,(byte) 0x81,(byte) 0x40,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x01,(byte) 0xC0,(byte) 0x80,(byte) 0x41,(byte) 0x00,(byte) 0xC1,(byte) 0x81,
        (byte)0x40
      } ;

      /* Table of CRC values for low–order byte */
      static byte auchCRCLo[] = {
        (byte)0x00,(byte) 0xC0,(byte) 0xC1,(byte) 0x01,(byte) 0xC3,(byte) 0x03,(byte) 0x02,(byte) 0xC2,(byte) 0xC6,(byte) 0x06,(byte) 0x07,(byte) 0xC7,(byte) 0x05,(byte) 0xC5,(byte) 0xC4,
        (byte)0x04,(byte) 0xCC,(byte) 0x0C,(byte) 0x0D,(byte) 0xCD,(byte) 0x0F,(byte) 0xCF,(byte) 0xCE,(byte) 0x0E,(byte) 0x0A,(byte) 0xCA,(byte) 0xCB,(byte) 0x0B,(byte) 0xC9,(byte) 0x09,
        (byte)0x08,(byte) 0xC8,(byte) 0xD8,(byte) 0x18,(byte) 0x19,(byte) 0xD9,(byte) 0x1B,(byte) 0xDB,(byte) 0xDA,(byte) 0x1A,(byte) 0x1E,(byte) 0xDE,(byte) 0xDF,(byte) 0x1F,(byte) 0xDD,
        (byte)0x1D,(byte) 0x1C,(byte) 0xDC,(byte) 0x14,(byte) 0xD4,(byte) 0xD5,(byte) 0x15,(byte) 0xD7,(byte) 0x17,(byte) 0x16,(byte) 0xD6,(byte) 0xD2,(byte) 0x12,(byte) 0x13,(byte) 0xD3,
        (byte)0x11,(byte) 0xD1,(byte) 0xD0,(byte) 0x10,(byte) 0xF0,(byte) 0x30,(byte) 0x31,(byte) 0xF1,(byte) 0x33,(byte) 0xF3,(byte) 0xF2,(byte) 0x32,(byte) 0x36,(byte) 0xF6,(byte) 0xF7,
        (byte)0x37,(byte) 0xF5,(byte) 0x35,(byte) 0x34,(byte) 0xF4,(byte) 0x3C,(byte) 0xFC,(byte) 0xFD,(byte) 0x3D,(byte) 0xFF,(byte) 0x3F,(byte) 0x3E,(byte) 0xFE,(byte) 0xFA,(byte) 0x3A,
        (byte)0x3B,(byte) 0xFB,(byte) 0x39,(byte) 0xF9,(byte) 0xF8,(byte) 0x38,(byte) 0x28,(byte) 0xE8,(byte) 0xE9,(byte) 0x29,(byte) 0xEB,(byte) 0x2B,(byte) 0x2A,(byte) 0xEA,(byte) 0xEE,
        (byte)0x2E,(byte) 0x2F,(byte) 0xEF,(byte) 0x2D,(byte) 0xED,(byte) 0xEC,(byte) 0x2C,(byte) 0xE4,(byte) 0x24,(byte) 0x25,(byte) 0xE5,(byte) 0x27,(byte) 0xE7,(byte) 0xE6,(byte) 0x26,
        (byte)0x22,(byte) 0xE2,(byte) 0xE3,(byte) 0x23,(byte) 0xE1,(byte) 0x21,(byte) 0x20,(byte) 0xE0,(byte) 0xA0,(byte) 0x60,(byte) 0x61,(byte) 0xA1,(byte) 0x63,(byte) 0xA3,(byte) 0xA2,
        (byte)0x62,(byte) 0x66,(byte) 0xA6,(byte) 0xA7,(byte) 0x67,(byte) 0xA5,(byte) 0x65,(byte) 0x64,(byte) 0xA4,(byte) 0x6C,(byte) 0xAC,(byte) 0xAD,(byte) 0x6D,(byte) 0xAF,(byte) 0x6F,
        (byte)0x6E,(byte) 0xAE,(byte) 0xAA,(byte) 0x6A,(byte) 0x6B,(byte) 0xAB,(byte) 0x69,(byte) 0xA9,(byte) 0xA8,(byte) 0x68,(byte) 0x78,(byte) 0xB8,(byte) 0xB9,(byte) 0x79,(byte) 0xBB,
        (byte)0x7B,(byte) 0x7A,(byte) 0xBA,(byte) 0xBE,(byte) 0x7E,(byte) 0x7F,(byte) 0xBF,(byte) 0x7D,(byte) 0xBD,(byte) 0xBC,(byte) 0x7C,(byte) 0xB4,(byte) 0x74,(byte) 0x75,(byte) 0xB5,
        (byte)0x77,(byte) 0xB7,(byte) 0xB6,(byte) 0x76,(byte) 0x72,(byte) 0xB2,(byte) 0xB3,(byte) 0x73,(byte) 0xB1,(byte) 0x71,(byte) 0x70,(byte) 0xB0,(byte) 0x50,(byte) 0x90,(byte) 0x91,
        (byte)0x51,(byte) 0x93,(byte) 0x53,(byte) 0x52,(byte) 0x92,(byte) 0x96,(byte) 0x56,(byte) 0x57,(byte) 0x97,(byte) 0x55,(byte) 0x95,(byte) 0x94,(byte) 0x54,(byte) 0x9C,(byte) 0x5C,
        (byte)0x5D,(byte) 0x9D,(byte) 0x5F,(byte) 0x9F,(byte) 0x9E,(byte) 0x5E,(byte) 0x5A,(byte) 0x9A,(byte) 0x9B,(byte) 0x5B,(byte) 0x99,(byte) 0x59,(byte) 0x58,(byte) 0x98,(byte) 0x88,
        (byte)0x48,(byte) 0x49,(byte) 0x89,(byte) 0x4B,(byte) 0x8B,(byte) 0x8A,(byte) 0x4A,(byte) 0x4E,(byte) 0x8E,(byte) 0x8F,(byte) 0x4F,(byte) 0x8D,(byte) 0x4D,(byte) 0x4C,(byte) 0x8C,
        (byte)0x44,(byte) 0x84,(byte) 0x85,(byte) 0x45,(byte) 0x87,(byte) 0x47,(byte) 0x46,(byte) 0x86,(byte) 0x82,(byte) 0x42,(byte) 0x43,(byte) 0x83,(byte) 0x41,(byte) 0x81,(byte) 0x80,
        (byte)0x40
      } ;

      static int CRC16(byte[] buffer, int usDataLen)
      {
         byte uchCRCHi = (byte)0xFF ; /* high byte of CRC initialized */
         byte uchCRCLo = (byte)0xFF ; /* low byte of CRC initialized */
         int uIndex ; /* will index into CRC lookup table */
         int i=0;

         while (usDataLen-- > 0) /* pass through message buffer */
         {
          uIndex = uchCRCHi ^buffer[i] & 0xFF ; /* calculate the CRC */
          uchCRCHi = (byte)(uchCRCLo ^ auchCRCHi[uIndex]) ;
          uchCRCLo = auchCRCLo[uIndex] ;
          i++;
         }

        return (uchCRCHi << 8 | uchCRCLo) ;
        }
    }

使用的代码是:

byte[] testbuffer = {0x01, 0x05, 0x00, 0x01, (byte) 0xFF, 0x00};
int crcresult;
crcresult = CalculateCRCByte.CRC16(testbuffer, 6);
System.out.println(crcresult);

我已将CRC16中的“Buffer”类型从char []转换为byte []。

当我在第5个字节中输入0xFF时计算CRC,crc计算不正确。通过其他方法,我们得到{0x01,0x05,0x00,0x01,(byte)0xFF,0x00}的CRC作为“DD FA” 而上面的crc计算给出了crc为“FF FA”。

我想每当我们必须在byte []中放入(byte)类型转换时,就像在上面的字节数组中一样,我们在FF前面放置了(byte),crc计算就会出错。

在上面的计算中使用char而不是byte时,crc计算是正确的。

/////////////////////////////////////////////// ///////////////////////////////////

另一个选择

我使用了

的查找表
http://introcs.cs.princeton.edu/java/51data/CRC16.java.html

代码是

byte[] bytes1= {0x01, 0x05, 0x00, 0x01, (byte) 0xFF, 0x00};

int crc = 0x0000;
for (byte b : bytes1) {
    crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff];
}

System.out.println();
System.out.println("CRC16 = " + Integer.toHexString(crc));

但输出是

CRC16 = e1dd

这里我认为字节是相反的。如果字节反转,则输出应为FADD

1 个答案:

答案 0 :(得分:0)

您隐式地从索引转换为int:

uIndex = uchCRCHi ^buffer[i] ; /* calculate the CRC */

由于字节是有符号的,当uchCRCHi或buffer [i]为负值时,uInde​​x也是负数。您需要将高位掩码为零,因此索引不会超出数组:

uIndex = (uchCRCHi ^ buffer[i]) & 0xFF; /* calculate the CRC */
相关问题