8

android/javaでチェックサム計算関数を作成しました。次のような機能

void CalculateCheckSum( byte[] bytes ){
     short CheckSum = 0, i = 0;
     for( i = 0; i < bytes.length; i++ ){
        CheckSum = (short) ((short)CheckSum + (short)bytes[i]);
     }

     Log.i("Checksum", Integer.toHexString(CheckSum));
}

チェックサム計算の入力値は、0xEF、0x01、0xEF、0x01、0x33、0x0C、0xB8、0xE5、0xFC、0x34、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFFです。チェックサム値を手動で計算したところ、結果は0xCE4です。上記の関数を使用すると、0xFFFFFFE4として回答が得られます。計算に誤りがありますか?ある場合は訂正してください。

ありがとう

4

6 に答える 6

2

ここでの問題はの(short)キャストですbytes[i]。標識を拡張します。(short)bytes[i]に変更する必要があります(bytes[i] & 0xff)。これはあなたに正しい答えを与えるでしょう。

他のほとんどの答えとは異なり、バイトオーバーフローとは何の関係もありません。配列タイプも変更する必要はありません。

于 2012-09-11T07:57:26.297 に答える
2

デバッガーを使用してコードをデバッグします。ただし、一般的に、を追加し続けると、intまたはを使用してもlong、ある時点でオーバーフローすることになり、予期しない結果が発生します。CRC32標準のチェックサムアルゴリズム、またはまたはなどのすでに利用可能なクラスの1つを使用するのが最適Adler31です。コードに関しては、結果を整数として扱っているようですが、shortそもそもなぜキャストするのでしょうか。

Javaはすべての算術計算をint'sを使用して実行するため、bytesはに変換さintれ、バイトに収まらないものはint' s:ffffffef(-17)のようになります。当然、必要なのは実際のバイト値だけなので、を使用して他のすべてをゼロにする必要があります(0xff & b)。したがって、ループは次のようになります。

  int checkSum = 0;

  for(byte b : bytes){
    checkSum += (0xff & b);
  }
于 2012-09-11T07:31:34.817 に答える
1

byteJavaドキュメントによると :

バイトの値の範囲は2^(-7)(2^7)-1(-128〜127)です。

しかし、あなたの値0xEF(10進数の239)はすでに1バイトの制限に達しています。それが、合計が間違った数値を与える原因です。

于 2012-09-11T07:25:22.553 に答える
1

aprianが前述したように、byteには16進値に必要な8ビットがありますが、格納できるのは-128〜127の値のみです。したがって、この場合は、次に大きいプリミティブを使用するのが迅速で簡単な解決策になりますshort

short shorts[] = {0xEF, 0x01, 0xEF, 0x01, 0x33, 0x0C, 0xB8, 0xE5, 0xFC, 0x34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

int checkSum = 0;

for( short s : shorts){
    checkSum = checkSum + s;
}

System.out.println("Checksum: " + Integer.toHexString(checkSum));

それは私に出力を与えます:

Checksum: ce4

もちろん、これはbyte array事前に変換する必要があるかもしれないことを意味します。

于 2012-09-11T07:45:28.763 に答える
0

ついに私は...

修正されたコード

void CalculateCheckSum( byte[] bytes ){
         short CheckSum = 0, i = 0;
         for( i = 0; i < bytes.length; i++){
              CheckSum += (short)(bytes[i] & 0xFF);
         }
         Log.i("Checksum", Integer.toHexString(CheckSum));
    }

aprianなどに感謝します

于 2012-09-11T08:01:19.897 に答える
-1

整数を次のように変換する場合は、入力として整数を使用する必要があります。

    String CalculateCheckSum( Integer[] bytes ){
        Integer CheckSum = 0, i = 0;
        for( i = 0; i < bytes.length; i++ ){
            CheckSum += bytes[i];
        }
        return Integer.toHexString(CheckSum);
    }

これにより、予想される0xCE4が返されます。これで問題が解決したことを願っています。

于 2012-09-11T07:37:56.530 に答える