вычисление контрольной суммы от Python к Java - PullRequest
0 голосов
/ 12 января 2010

Я получил этот скрипт Python, который генерирует контрольную сумму файла:

import sys,os

if __name__=="__main__":
#filename=os.path.abspath(sys.argv[1])
#filename=r"H:\Javier Ortiz\559-7 From Pump.bin"
cksum=0
offset=0
pfi=open(filename,'rb')
while 1:
  icks=0
  chunk=pfi.read(256)
  if not chunk:  break     #if EOF exit loop

  for iter in chunk:
    icks+=ord(iter)
    print ord(iter)
  cksum=(cksum+icks) & 0xffff
pfi.close()
print "cksum=0x%4.4x"%cksum

И я пытаюсь преобразовать его в Java, но я не получаю те же результаты.

Вот мой код Java:

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ChecksumCalculator {

private ChecksumCalculator() {
}

public static int getChecksum(File file) {
    int cksum = 0;
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    DataInputStream dis = null;
    try {
        fis = new FileInputStream(file);

        // Here BufferedInputStream is added for fast reading.
        bis = new BufferedInputStream(fis);
        dis = new DataInputStream(bis);
        byte[] buffer = new byte[256];
        // dis.available() returns 0 if the file does not have more lines.
        while (dis.read(buffer) != -1) {
            int icks = 0;
            for (byte b : buffer) {
                icks += b & 0xff;
                System.out.println(b & 0xff);
            }
            cksum = (cksum + icks) & 0xffff;
            System.out.println("Checksum: " + cksum);
        }

        // dispose all the resources after using them.
        fis.close();
        bis.close();
        dis.close();
        return cksum;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return -1;
    } catch (IOException e) {
        e.printStackTrace();
        return -1;
    }
}

static public void main(String[] s) {
    System.out.println("0x" + getChecksum(new File("H:\\Javier Ortiz\\559-7 From Pump.bin")));
}

}

Но я получаю разные результаты для файла. Например, если я запускаю его в простом текстовом файле, содержащем только слово test, он выдает следующий результат:

python: cksum = 0x01c0 java: cksum = 0x448

Есть идеи?

Ответы [ 3 ]

5 голосов
/ 12 января 2010

Ваша версия Python печатает контрольную сумму в шестнадцатеричном формате, а ваша версия Java - в десятичном виде Вы должны также напечатать свою версию Java в шестнадцатеричном формате. 0x1c0 == 448.

Чтобы использовать строку формата cksum=0x%4.4x, как это было в вашей версии Python, используйте это:

System.out.printf("cksum=0x%4.4x%n", ...);

или даже лучше

System.out.printf("cksum=%#04x%n", ...);

Кроме того, вам не нужно DataInputStream для этого. Просто используйте bis.read(buffer) вместо dis.read(buffer).

3 голосов
/ 12 января 2010

1C0 16 = 448 10

Я думаю, что это твоя проблема.

1 голос
/ 12 января 2010
  1. dis.read(buffer) возвращает количество байтов, которые были фактически прочитаны. Для последней порции она, вероятно, будет меньше 256. Так что цикл for не всегда должен выполняться 256 раз - он должен выполняться столько раз, сколько фактическое число байтов было прочитано из потока.

  2. Я не разработчик Python, но это не похоже на ord(icks) в Python делает то же самое, что b & 0xff в Java.

  3. Имейте в виду, что все типы Java подписаны; это может повлиять на расчет.

Кроме того, хотя это не влияет на корректность - рекомендуется очистить все ресурсы (т.е. закрыть потоки) в блоке finally.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...