python到Java校验和计算

时间:2010-01-12 16:09:05

标签: java python

我收到了这个生成文件校验和的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的普通txt文件上运行它,它会给出以下结果:

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

有什么想法吗?

3 个答案:

答案 0 :(得分:5)

您的Python版本以十六进制格式打印校验和,而Java版本以十进制格式打印。您也应该使您的Java版本以十六进制格式打印。 0x1c0 == 448。

要使用Python版本中的cksum=0x%4.4x格式字符串,请使用:

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

甚至更好

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

此外,您不需要DataInputStream。只需使用bis.read(buffer)代替dis.read(buffer)

答案 1 :(得分:3)

1C0 16 = 448 10

我认为这是你的问题。

答案 2 :(得分:1)

  1. dis.read(buffer)返回实际读取的字节数。对于最后一个块,它可能小于256.因此for循环不应总是执行256次 - 它应该执行与从流中读取的实际字节数一样多的次数。 / p>

  2. 我不是Python开发人员,但它看起来不像Python中的ord(icks)和Java中的b & 0xff一样。

  3. 请记住,所有Java类型都已签名;这可能会影响计算。

  4. 此外,虽然这不会影响正确性 - 但最好清除finally块中的所有资源(即关闭流)。