3

我从硬件合作伙伴那里收到了一个用 C 语言编写的 CRC 函数。他的设备发送的消息使用此代码进行签名。谁能帮我把它翻译成Java?

int8 crc8(int8*buf, int8 data_byte)
{
    int8 crc=0x00;
    int8 data_bit=0x80;
    while(data_byte>0)
    {
        if(((crc&0x01)!=0)!=((buf[data_byte]&data_bit)!=0))
        {
            crc>>=1;
            crc^=0xCD;
        }
        else 
            crc>>=1;
        data_bit>>=1;
        if(!data_bit)
        {
            data_bit=0x80;
            data_byte--;
        }
    }
    return(crc);
}

我试图将其转换为 Java,但结果不是我所期望的。

public static byte crc8(byte [] buf, byte data_byte)
{
  byte crc = 0x00;
  byte data_bit = (byte)0x80;
  while(data_byte>0)
  {
    if(((crc&0x01)!=0)!=((buf[data_byte]&data_bit)!=0))
    {
      crc>>=1;
      crc^=0xCD;
    }
    else
    {
      crc>>=1;
    }
    data_bit>>=1;
    if(data_bit == 0)
    {
      data_bit= (byte)0x80;
      data_byte--;
    }
  }
  return crc;
}

我想这是错误:if(data_bit != 0)

编辑:

我在转换方法中将代码更改为字节。我从一个套接字接收我的数据并将其转换为一个字符串,我从中得到一个 byteArray。

输入示例是 16, 0, 1, -15, 43, 6, 1, 6, 8, 0, 111, 0, 0 ,49 其中最后一个字段 (49) 应该是校验和

我也试过 Durandals 版本,但我的结果仍然无效。

这就是我读取数据的方式

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
char[] buffer = new char[14];
int count= bufferedReader.read(buffer, 0, 14); 
String msg = new String(buffer, 0, count);
byte[] content = msg.getBytes();
4

2 回答 2

2
if(!data_bit)

翻译成

if(data_bit == 0)

你真的需要使用字节而不是短裤。要解决您使用字节时遇到的问题,请使用此

byte data_bit = (byte)0x80;

此外,正如 Mark 所说,您需要使用 >>> 而不是 >>。

于 2013-11-04T15:11:26.697 回答
0

将代码 1:1 翻译,特别注意对字节执行的所有操作以说明 java 隐式转换为 int(例如 (byte >>> 1) 绝对没有价值,因为字节首先扩展为 int,移动然后再转换回,无论如何使它有效地成为一个有符号的转变)。

因此,局部变量最好声明为 int,并且当从掩码的 bytearray 加载以产生无符号扩展时: int x = byte[i] & 0xFF; 因为在唯一完成的地方,数据已经被屏蔽到一个位(在 if 中),所以没有什么特别的事情要做。

应用到 C 代码产生:

int crc8(byte[] buf, int dataCount) {
    int crc = 0;
    int data_bit = 0x80;
    while(dataCount > 0) {
        if ( ((crc & 0x01)!=0) != ((buf[dataCount] & data_bit)!=0)) {
            crc >>= 1;
            crc ^= 0xCD;
        } else {
            crc >>= 1;
        }
        data_bit >>= 1;
        if (data_bit == 0) {
            data_bit = 0x80;
            dataCount--;
        }
    }
    return crc;
}

也就是说,代码效率不高(它逐位处理输入,有更快的实现处理整个字节,对每个可能添加的字节使用一个表,但您可能不关心这个用例)。

另外,当您将此方法的 crc 与一个字节进行比较时,您必须使用 0xFF 正确屏蔽该字节,否则对于值 >=0x80 的比较将失败:

(int) crc == (byte) crc & 0xFF

编辑:

我什至对原始代码感到担心的是,data_byte 显然是为了指定一个长度,首先它以相反的顺序计算,而且它会在指定的数字之后访问一个额外的字节(data_byte 在循环之前不会递减)。我怀疑原始代码(已经)损坏了,或者对它的调用非常混乱。

于 2013-11-04T17:40:44.690 回答