4

我正在将一个用 Delphi 编写的旧应用程序移植到 Java。我在使用这个函数时遇到了一些问题,它计算了传输消息的 CRC。

这是原始代码:

       if(ReceivedMessage[slot].Message[1] = $FD) and
          (ReceivedMessage[slot].MessageLength in [1..16]) and
          (ReceivedMessage[slot].Message[counter] = $FF) then
       begin
        index := 2;
        ReceivedMessage[slot].DataReady := TRUE;

        for counter := 1 to ReceivedMessage[slot].MessageLength do
        begin
          Inc(index);

          if ReceivedMessage[slot].Message[index] < $F8 then
            ReceivedMessage[slot].Data[counter] := ReceivedMessage[slot].Message[index]
          else
          if ReceivedMessage[slot].Message[index] = $F8 then
          begin
            Inc(index);

            ReceivedMessage[slot].Data[counter] := ReceivedMessage[slot].Message[index] or $F0;
          end
          else
            ReceivedMessage[slot].DataReady := FALSE;  // Invalid data
        end;

        if ReceivedMessage[slot].DataReady = TRUE then
        begin
          Inc(index);

          if ReceivedMessage[slot].Message[index] < $F8 then
            ReceivedMessage[slot].CRC := ReceivedMessage[slot].Message[index] shl 8
          else
          if ReceivedMessage[slot].Message[index] = $F8 then
          begin
            Inc(index);

            ReceivedMessage[slot].CRC := (ReceivedMessage[slot].Message[index] or $F0) shl 8;
          end;

          Inc(index);

          if ReceivedMessage[slot].Message[index] < $F8 then
            ReceivedMessage[slot].CRC := ReceivedMessage[slot].CRC or ReceivedMessage[slot].Message[index]
          else
          if ReceivedMessage[slot].Message[index] = $F8 then
          begin
            Inc(index);

            ReceivedMessage[slot].CRC := ReceivedMessage[slot].CRC or        ReceivedMessage[slot].Message[index] or $F0;
          end;

这是我的Java代码:

 if(array[1]==0xFD && (array[2]>0 && array[2]<17) && array[pos]==(byte)0xFF)
 {
index=2;
for(int counter=1;counter<splMsg.nbytes+1;counter++)
{
     index++;
 if(array[index]<0xF8)
     data[counter]=array[index];
 else
     if(array[index]==0xF8)
     {
      index++;
      data[counter]=(byte)(array[index] | 0xF0);
     }
     else
         return 0xFC; 
}


index++;
short crc=0x0000;

if(array[index]<0xF8)
     crc=(short) (array[index]<<8);
else
   if(array[index]==0xF8)
   {
    index++;
    crc=(short)((array[index] | 0xF0) << 8);
   }
index++;
if(array[index]<0xF8)
    crc=(short) (crc | array[index]);
else
   if(array[index]==0xF8)
   {
    index++;
    crc=(short)(crc | array[index] | 0xF0);
   }

msgcrc=new byte[] {(byte)(crc >> 8 & 0xff),(byte)(crc & 0xff)};

我的函数大多数时候返回传输的 CRC 码,但有时会失败并返回消息的最后两个字节。消息的最后 3 个字节是 CRC 码(2 个字节)和消息结束 0xff 字节。

有什么帮助吗?

谢谢,佩德罗

4

1 回答 1

7

记住:

Java 字节已签名。所以:

byte test = (byte)255;
System.out.println(test);

将输出:-1

    byte test = (byte)255;
    System.out.println(test == 255);

将打印false,但是

    byte test = (byte)255;
    System.out.println((test & 255) == 255);

会做我认为你想要实现的(在这种情况下是 prints true)。

要获取无符号(字节)值,请使用(array[index] & 255).

您必须在任何地方使用 0xff 进行屏蔽,否则您将获得大于 127 的字节值的符号扩展整数。

对于比较,您也可以始终对byte(eg if(test == (byte)255)) 进行强制转换,但我认为应该坚持一次转换,所以我建议使用& 0xff掩蔽。

于 2013-02-15T11:19:54.317 回答