2017-08-01 1 views
-4

Mon programme lit un fichier, calcule une somme de contrôle de 4 octets en traitant le fichier comme des entiers de quatre octets et en additionnant chaque bloc, puis le compare à une somme de contrôle pré-calculée pour vérifier la validité du fichier.Pourquoi mon code ne renvoie-t-il pas la somme de contrôle que j'attends et que j'ai pré-calculée?

Par exemple, hello_world.txt peut contenir les éléments suivants.

Bonjour tout le monde

Je précalculée la somme de contrôle, et je sais qu'il est 0x49f247db, mais la comparaison à la fin échoue.

Quel pourrait être le problème ici? Est-ce la façon dont j'obtiens les entiers à 4 octets? J'ai essayé de le faire en transformant le pointeur du tampon en un pointeur entier et en itérant juste sur le tampon avec l'opérateur '++', mais cela finirait par sauter des octets.

Ceci est le code que j'utilise.

#include <sys/stat.h> 
    #include <fcntl.h> 
    #include <stdio.h> 
    #include <unistd.h> 
    #include <errno.h> 
    #include <string.h> 


    int main() { 
     unsigned char buffer [1024]; 
     unsigned long int  checksum = 0; 
     FILE      *fp; 
     int       i; 
     unsigned long int  length; 

     fp = open ("hello_world.txt", 0, 0); 

     if (fp == NULL) exit(0); 

     for (;;) 
      { 
      memset (buffer, 0, sizeof(buffer)); 
      /* Read the next chunk of the file */ 
      length = read (fp, &buffer, 1024); 
      if (length == 0) 
       break; 

      printf("i'm here. %d %s \n", length, strerror(errno)); 
      /* We've read a chunk of the file -- all chunks (except the last) 
       * will be '1024' bytes in length; the last chunk will 
       * probably be less than '1024' bytes. 
       */ 
      for (i=0; i<length; i+=4) 
       { 
       unsigned long int a = (unsigned long int) ((unsigned char)(buffer[i]) << 24 | 
          (unsigned char)(buffer[i+1]) << 16 | 
          (unsigned char)(buffer[i+2]) << 8 | 
          (unsigned char)(buffer[i+3])); 
       checksum += a; 
       } 
      } 

     printf("%d, %x \n", checksum, checksum); 
     if (0x49f247db == checksum) printf("CHECKSUM MATCHED"); 
     /* Close the file and return the checksum */ 
     close (fp); 
     return 0; 
    } 
+5

La magie peut arriver. Non, en fait, ça ne peut pas. Où est ton code? –

+3

'a = 10; b = 16; printf ("% u% x \ n", a, b); '- au moins, ils impriment la même chose. – chux

+3

C'est peut-être parce que les deux nombres sont réellement différents. C'est peut-être parce que vous les avez imprimées en utilisant une technique incorrecte («% d», peut-être) qui les rendait par inadvertance identiques. C'est peut-être parce que quelque chose les a changé entre le moment où vous les avez imprimés et les a comparés. Pourquoi ne nous montrez-vous pas votre code, alors nous n'avons pas à deviner? –

Répondre

0

Je définis ma variable de contrôle unsigned long int parce que c'était typedefed comme uint4 dans la bibliothèque, je suis PORTAGE (où la base de ce code vient). Il s'avère que la bibliothèque n'était utilisée que sur les architectures 32 bits, donc un entier long non signé est de 4 octets alors que sur ma machine (64 bits) c'est 8 octets. Changer la variable en un entier non signé a tout fixé, mais j'ai besoin de beaucoup de travail pour porter la bibliothèque de 32 bits à 64 bits.

Aussi j'aurais dû utiliser% lx au lieu de% x.