0

JavaでSegaGenesisROMファイルのチェックサムを計算しようとしています。このために、Cから切り取ったコードをJavaに移植したいと思います。

static uint16 getchecksum(uint8 *rom, int length)
{
  int i;
  uint16 checksum = 0;

  for (i = 0; i < length; i += 2)
  {
    checksum += ((rom[i] << 8) + rom[i + 1]);
  }

  return checksum;
}

コードの機能を理解しています。すべての16ビット数を合計します(2つの8ビット数を組み合わせたもの)。しかし、私が理解していなかったのは、uint16のオーバーフローで何が起こっているのか、そしてこれがどのようにJavaコードに転送されるのかということです。

編集:このコードは機能しているようです、ありがとう:

int calculatedChecksum = 0;
int bufferi1=0;
int bufferi2=0;
bs = new BufferedInputStream(new FileInputStream(this.file));

bufferi1 = bs.read();
bufferi2 = bs.read();
while(bufferi1 != -1 && bufferi2 != -1){
    calculatedChecksum += (bufferi1*256 + bufferi2);
    calculatedChecksum = calculatedChecksum % 0x10000;
    bufferi1 = bs.read();
    bufferi2 = bs.read();
}
4

3 に答える 3

1

簡単に言えば、オーバーフローは失われます。より正しいアプローチ(imho)は、合計にuint32を使用することです。これにより、合計が下位16ビットになり、オーバーフローが上位16ビットになります。

于 2012-08-28T22:46:18.657 に答える
1
static int checksum(final InputStream in) throws IOException {
  short v = 0;
  int c;
  while ((c = in.read()) >= 0) {
    v += (c << 8) | in.read();
  }
  return v & 0xffff;
}

これは同等に機能するはずです。を使用すると、算術オーバーフローはビットと同じである& 0xffffため、値を常に符号なしであるかのように扱うことができます。v

于 2012-08-28T23:31:35.377 に答える
0

2 16を法とする加算が必要です。これは、手動で簡単に綴ることができます。

checksum = (checksum + ((rom[i] << 8) + rom[i + 1])) % 0x10000;
//                                                   ^^^^^^^^^
于 2012-08-29T05:56:47.503 に答える