0

Delhpi には、送信されたメッセージの CRC を計算するこの関数があります。この関数は 2 バイトの CRC を返す必要がありますが、一部のメッセージでは CRC の長さが 3 バイトです。

以下にいくつかの例を示します。

メッセージ 0588080168F8 --> CalculateCRC(0588080168F8,5)=083D9B (3 バイト)

メッセージ 0588080168F0 --> CalculateCRC(0588080168F0,5)=BC93 (2 バイト)

元のデルファイ コードは次のとおりです。

procedure CalculateCRC(var Message: TMessage);
var
  counter: byte;
  counter1: byte;
begin
  for counter := 1 to Message.MessageLength + 1 do
  begin
    if counter = 1 then
      Message.CRC := 0 xor (word(Message.MessageLength) shl 8)
    else
      Message.CRC := Message.CRC xor (word(Message.Data[counter-1]) shl 8);

    for counter1 := 1 to 8 do
    begin
      if (Message.CRC and $8000) = $8000 then
        Message.CRC := (Message.CRC shl 1) xor $1021
      else
        Message.CRC := Message.CRC shl 1;
    end;
  end;
end;

そして、ここに私のJava関数があります:

  public static byte[] calculateCRC(byte[] msg, int len)
  {
    int crc=0;

    for(int i=1; i<=len+1;i++)
    {
      if(i==1)
        crc= 0 ^ (len<<8);
      else
        crc=crc ^ ((msg[i-1] & 0xff) << 8);

      for(int j=1; j<=8;j++)
      {
        if((crc & 0x8000) == 0x8000)
          crc= (crc <<1 ) ^ 0x1021;
        else
          crc= (crc <<1 ) ;
      }
    }

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

このメソッドでは、HEX 文字列をバイト配列に変換します。

  private static byte[] hexToBytes(String s) 
  {
   int len = s.length();
   byte[] data = new byte[len / 2];
   for (int i = 0; i < len; i += 2) 
   {
    data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
   }
   return data;
  }

私のコードは 2 バイトの CRC で動作しますが、3 バイトのメッセージで正しい CRC を提供できません...何か助けやアイデアはありますか? ありがとう、ペドロ

4

1 に答える 1

2

Delphi コードのこの部分:

for counter := 1 to Message.MessageLength + 1 do
  begin
    if counter = 1 then
      Message.CRC := 0 xor (word(Message.MessageLength) shl 8)
    else
      Message.CRC := Message.CRC xor (word(Message.Data[counter-1]) shl 8);

1 から MessageLength+1 までカウントしています。そして、ロジックは、Message.Data の最初のインデックスが 1 であることを暗示しているようです。したがって、このコードは、Delphi の文字列インデックスが 1 から始まるという事実に基づいていると思います。しかし、Java ではそうではなく、0 から始まります。おそらく、Java メソッドを次のように書き直す必要があります。

    for (int i = 0; i <= len; i++)
    {
        if (i == 0)
            crc = 0 ^ (len << 8);
        else
            crc = crc ^ ((msg[i - 1] & 0xff) << 8);
于 2013-02-26T19:31:21.137 に答える