Python到Java的校验和计算

0 投票
3 回答
1355 浏览
提问于 2025-04-15 17:55

我收到了一段生成文件校验和的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 个回答

1
  1. dis.read(buffer) 这个命令会返回实际读取到的字节数。对于最后一段数据,读取的字节数可能会少于256。所以,for 循环不应该总是执行256次,而是应该根据实际从流中读取到的字节数来决定执行多少次。

  2. 我不是Python开发者,但看起来在Python中,ord(icks) 和在Java中的 b & 0xff 并不是同一个意思。

  3. 要记住,所有Java类型都是有符号的,这可能会影响计算结果。

另外,虽然这不会影响结果,但在finally 块中清理所有资源(比如关闭流)是个好习惯。

3

1C016表示的是一个十六进制的数字,它的值是44810,也就是十进制的448。

我觉得这就是你的问题所在。

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)就可以了。

撰写回答