代码之家  ›  专栏  ›  技术社区  ›  javydreamercsw

Python到Java校验和计算

  •  0
  • javydreamercsw  · 技术社区  · 15 年前

    我收到了生成文件校验和的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=0x44

    有什么想法吗?

    3 回复  |  直到 15 年前
        1
  •  5
  •   C. K. Young    15 年前

    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) .

        2
  •  3
  •   jdmichal    15 年前

    1C0 十六 = 448

    我想这是你的问题。

        3
  •  1
  •   Eli Acherkan    15 年前
    1. dis.read(buffer) 返回实际读取的字节数。对于最后一个块,它可能小于256。所以 for 循环不应该总是执行256次-它应该执行与从流中读取的实际字节计数相同的次数。

    2. 我不是Python开发人员,但看起来不像 ord(icks) 在python中与 b & 0xff 在Java中。

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

    此外,尽管这不会影响正确性,但清除 finally 块。