开发者

python to Java checksum calculation

I received this python script that generates a file checksum:

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

And I'm trying to convert it to Java but I'm not geting the same results.

Here's my Java code:

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.av开发者_如何学Pythonailable() 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")));
}

}

But I get different results on a file. For example if I run it on a plain txt file containing only the word test it gives out the following result:

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

Any idea?


Your Python version prints the checksum in hex, while your Java version prints it in decimal. You should make your Java version print in hex, too. 0x1c0 == 448.

To use the cksum=0x%4.4x format string as you had in your Python version, use this:

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

or even better

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

Also, you don't need a DataInputStream for this. Just use bis.read(buffer) instead of dis.read(buffer).


1C016 = 44810

I think that's your problem.


  1. dis.read(buffer) returns the number of bytes that was actually read. For the last chunk, it will probably be less than 256. So the for loop shouldn't always be performed 256 times - it should be performed as many times as the actual byte count that was read from the stream.

  2. I'm not a Python developer, but it doesn't look like ord(icks) in Python does the same as b & 0xff in Java.

  3. Keep in mind that all Java types are signed; this might affect the calculation.

Also, although this doesn't affect correctness - it's a good practice to clean all the resources (i.e. to close the streams) in a finally block.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜