用Java计算16位CRC并将其附加在字节数组的末尾 [英] Calculate 16 bit CRC in java and append it at the end of the byte array

查看:97
本文介绍了用Java计算16位CRC并将其附加在字节数组的末尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下缓冲区

byte pingBuff[] ={0x01, 0x01,0x00,0x01,0x00,0x20}

我需要计算这6个字节的16位CRC,并将其附加到

I need to calculate 16 bit CRC of these 6 bytes and append it at the end of the

pingBuff[]

我已经使用C ++做到了这一点,并试图像下面那样在Java中更改该代码,但是它没有用。

I have done it using C++ and tried to change that code in java like below but it didnot work.

    package org.totalbeginner.tutorial;

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

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

      int CRC16(char puchMsg, int usDataLen)
      {
         char uchCRCHi = 0xFF ; /* high byte of CRC initialized */
         char uchCRCLo = 0xFF ; /* low byte of CRC initialized */
         int uIndex ; /* will index into CRC lookup table */

         while (usDataLen--) /* pass through message buffer */
         {
          uIndex = uchCRCHi ^ puchMsg++ ; /* calculate the CRC */
          uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
          uchCRCLo = auchCRCLo[uIndex] ;
         }

        return (uchCRCHi << 8 | uchCRCLo) ;
        }

    }

在线

while (usDataLen--)

看到的错误是无法从int转换为boolean

the error seen is "cannot convert from int to boolean"

并在行中

uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;

看到的错误是无法从int转换为char

the error seen is "cannot convert from int to char"

实际上,c中的代码使用了无符号char,我将它们转换为char。我在此java实现中将uninged short转换为int。

Actually the code in the c used unsigned char , i converted them to char . and i converted unsinged short to int in this java implementation.

请提出如何改进这种crc计算方法的建议。
还是有其他方法可以从hex bytes计算crc。我搜索了其他方法,但它不适用于pingBuff []中的十六进制字节。

Please suggest how can i improve this method of crc calculation . Or is there any other way of calculating crc from hex bytes . I have searched other method but it didnot work for the hex bytes in pingBuff[].

推荐答案

关于第一个问题:在< a href = / questions / tagged / c class = post-tag title =显示已标记'c' rel = tag> c 的问题(或的问题), int 0 中的code>评估为 false ,其他任何值评估为 true 。 Java不会执行这些隐式强制转换,因此您需要手动检查 int 是否大于 0 (请参阅更正1)。

Regarding the first issue: in c (or c++ for that matter), an int of 0 is evaluated as false, and any other value is evaluated to true. Java does not perform these implicit casts, so you need to manually check your int is larger than 0 (see "correction 1" in the code below).

关于第二个问题:在Java中,仅定义 ^ 运算符在 int s之间。因此,当您在两个 char 上执行时,它们都被提升为 int s,然后才进行异或。结果当然是 int ,它不能分配给 char -您必须明确地将其还原为一个字符。请注意,由于已知两个 int 的MSB均为零(因为它们是从 char s提升的),

Regarding the second issue: in Java, the ^ operator is defined only between ints. So when you perform in on two chars, they are both promoted to ints and only then XORed. The result is, of course, an int, which cannot be assigned to a char - you must explicitly cast it back down to a char. Note that since the MSBs of both ints are known to be zeros (as they were promoted from chars), this is perfectly safe, and does not risk any data loss.

  int CRC16(char puchMsg, int usDataLen)
  {
     char uchCRCHi = 0xFF ; /* high byte of CRC initialized */
     char uchCRCLo = 0xFF ; /* low byte of CRC initialized */
     int uIndex ; /* will index into CRC lookup table */

     // Correction 1: compare the int to 0
     while (usDataLen-- > 0) /* pass through message buffer */
     {
      uIndex = uchCRCHi ^ puchMsg++ ; /* calculate the CRC */
      uchCRCHi = (char) (uchCRCLo ^ auchCRCHi[uIndex]); // Correction 2: explicit ca
      uchCRCLo = auchCRCLo[uIndex] ;
     }

    return (uchCRCHi << 8 | uchCRCLo) ;
    }

这篇关于用Java计算16位CRC并将其附加在字节数组的末尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆