2010-01-12 3 views
0

J'ai reçu ce script python qui génère une somme de contrôle du fichier:python pour le calcul Java somme de contrôle

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 

Et je suis en train de le convertir en Java, mais je ne suis pas geting les mêmes résultats.

Voici mon code 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"))); 
} 

}

Mais j'obtiens des résultats différents sur un fichier. Par exemple, si je l'exécute sur un fichier txt simple contenant uniquement le mot tester donne le résultat suivant:

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

Toute idée?

+0

Utilisez la journalisation et comparez les endroits où les accès sont mauvais. – Tobu

Répondre

5

Votre version Python imprime la somme de contrôle en hexadécimal, tandis que votre version Java l'imprime en décimal. Vous devriez aussi imprimer votre version Java en hexadécimal. 0x1c0 == 448.

Pour utiliser la chaîne de format cksum=0x%4.4x que vous aviez dans votre version Python, utilisez ceci:

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

ou mieux encore

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

, vous n'avez pas besoin un DataInputStream pour cela. Il suffit d'utiliser bis.read(buffer) au lieu de dis.read(buffer).

+0

L'utilisation de bis.reader m'a donné les mêmes valeurs de icks. Une idée sur la façon d'imprimer des hexs en Java? J'ai essayé java.lang.Integer.toHexString sans voir de changement. – javydreamercsw

+0

L'utilisation de votre format System.out produit toujours des sorties 0x448 – javydreamercsw

+0

Cela ne vous dérange pas le dernier commentaire. J'avais juste besoin de nettoyer et de construire. Merci! – javydreamercsw

3

1C0 = 448

Je pense que c'est votre problème.

1
  1. dis.read(buffer) renvoie le nombre d'octets réellement lus. Pour le dernier bloc, il sera probablement inférieur à 256. Donc la boucle for ne devrait pas toujours être exécutée 256 fois - elle devrait être effectuée autant de fois que le nombre réel d'octets lu dans le flux. Je ne suis pas un développeur Python, mais il ne ressemble pas ord(icks) en Python fait la même chose que b & 0xff en Java. Gardez à l'esprit que tous les types Java sont signés; Cela pourrait affecter le calcul.

En outre, bien que cela ne porte pas atteinte correct - il est une bonne pratique pour nettoyer toutes les ressources (par exemple pour fermer les cours d'eau) dans un bloc finally.

+0

Merci. Changé cette ligne à: pour (int i = 0; i javydreamercsw

+0

ord() fait la même chose que b & 0xff, convertir de byte en ascii. – javydreamercsw