Comment comparer 2 fichiers bit à bit ?

Bonjour à tous et encore merci pour votre aide et patience pour les « non professionnel » en programmation.
Pourquoi ce programme, l’anecdote vaut le coup : Je bosse normalement dans le son. J’ai quelques personnes autour de moi dissent que le son change si l’on fait des copies.
Ce petit programme va donc servir simplement à comparer deux exemplaires d’un même fichier copié x fois et nous dire s’il y des différences.
On en déduira que non et donc que la différence de son est due : au débit du matériel de stockage, à l’interface de ce matériel de stockage, au logiciel en fonction de la piste utilisé ( algo interne )… à voir.

Peut être avec vous une autre méthode… je suis toujours preneur.

Voici la mienne :
J’utilise deux Flux : A et B et je les compare.

1er test avec le .tellg() sur le fluxB en commentaire.
Pour commencer je ne comprends pas pourquoi ligne 44 :
Si je fait un .tellg () sur un seul des flux ils commence à se décaler. Comme si la lecture de la position faisait avancer le pointeur de flux d’un octet. Normal ou étrange ?

2eme test en activant les deux .tellg()
Là la comparaison entre deux fichiers identique se passe bien mais je ne comprends le pas entre deux positions. Vu que j’ai mis une variable « bufferSize » pour remplir un tableau de 10char = 10 octets avec le flux. Et meme si je me trompe dans le nombre d’octet (char = 1/2octet ou 2*octets) le pas devrait être régulier.
Sur un petit fichier 213 Oct le pas diminue : 45 – 41 – 36 – 26 – 22 – 17 – 16 - 10
Et le pas change aussi en fonction de la taille des fichiers : sur un fichier de 170ko j’obtiens des pas de 10 à 494.
Mystère !

Du coup j’ai vraiment l’impression de ne pas bien comparer les ficher et des sauter des informations. Merci d’avance.

Le code fonctionne. Pour l’utiliser mettre au niveau de l’exécutable deux fichiers renommé : testA.txt et testB.txt
c’est juste que l’application une fois finie aura une petite interface graphique créé avec la lib Qt.

main.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
#include <QApplication>
#include <string>
#include <iostream>
#include <fstream>
#include "CompareFiles.h"
 
int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
 
    CompareFiles test;
 
    return app.exec();
}
CompareFiles.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef COMPAREFILES_H
#define COMPAREFILES_H
 
 
class CompareFiles
{
  public:
    CompareFiles(std::string a ="testA.txt", std::string b="testB.txt", int buff = 10, int delta = 4);
    virtual ~CompareFiles();
  protected:
  private:
    void compare();
    double tailleFichier( std::ifstream *flux );
    void affichageDiff(int i);
    void affichageDiff(char* bufA, char* bufB, int i);
 
    std::ifstream fluxA;
    std::ifstream fluxB;
    double tailleA, tailleB;
    int bufferSize;
    int deltaDiff;
};
 
#endif // COMPARFILES_H
CompareFiles.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <string>
#include <iostream>
#include <fstream>
#include <bitset>
#include "CompareFiles.h"
 
 
using namespace std;
 
CompareFiles::CompareFiles(string a , string b , int buff, int delta )
                        : bufferSize(buff), deltaDiff(delta)
{
  fluxA.open( a.c_str(), ios::in );
  if ( fluxA ) tailleA = tailleFichier ( &fluxA );
  else cerr << "Probleme dans le constructeur du flux A" << endl;
 
  fluxB.open( b.c_str(), ios::in );
  if ( fluxB ) tailleB = tailleFichier ( &fluxB );
  else cerr << "Probleme dans le constructeur du flux B" << endl;
 
  compare();
  cerr << "Fin";
}
 
void CompareFiles::compare(){
  int positionA, positionB;
  char*bufferA;
  char*bufferB;
 
  if ( tailleA == tailleB ) {
    // allocate memory:
    bufferA = new char [bufferSize];
    bufferB = new char [bufferSize];
 
    double counter = 0;
    while ( fluxA.good() && fluxB.good() && fluxA.tellg()< tailleA ) {
 
      // read data as a block:
      fluxA.readsome (bufferA,bufferSize);
      fluxB.readsome (bufferB,bufferSize);
 
      cerr << "position du flux : " << fluxA.tellg() << endl;
      // !!!!!!!!!!!!!!!!!!!!!!!!!!
      cerr << "position du flux : " << fluxB.tellg() << endl; // ici faut m'expliquer
      // !!!!!!!!!!!!!!!!!!!!!!!!!!
 
      for ( int i=0; i<bufferSize; i++ ) {
        if ( bufferA[i] != bufferB[i] ) {
          positionA = fluxA.tellg(); // On garde la position pour y revenir.
          positionB = fluxB.tellg(); // On garde la position pour y revenir. Normalement ils devraient avoir la meme position.
 
          cerr << "position du fluxA detect Err: " << positionA << endl;
          cerr << "position du fluxB detect Err: " << positionB << endl;
          cerr << "counter : " << counter << "  bufferSize : " << bufferSize << "  i : " << i << endl;
          cerr << "difference entre A et B à l'octet : " << counter*bufferSize + i << endl;
 
          affichageDiff(bufferA, bufferB, i);
          fluxA.seekg(positionA);
          fluxB.seekg(positionB);
        }
      }
      counter++;
    }
 
    delete[] bufferA;
    delete[] bufferB;
 
  }
  else cerr << "la taille des fichiers est differente" << endl;
}
 
double CompareFiles::tailleFichier( ifstream *flux ) {
  // determine la taille d'un fichier
  double length;
  flux->seekg (0, ios::end);
  length = flux->tellg();
  flux->seekg (0, ios::beg);
  cout << "taille " << length << endl;
  return length;
}
void CompareFiles::affichageDiff(int i){
 
  cerr << "position err : " << i << endl;
 
  if (i>deltaDiff) i-=deltaDiff;
  else i=0;
 
  cerr << "position du flux pour err : " << i << endl;
 
  fluxA.seekg(i);
  fluxB.seekg(i);
 
  for ( int k = 0; k<2; k++){
    if (k==0){
      cerr << "A : ";
      //fluxA.seekg(i);
    }
    else {
      cerr << "B : ";
      //fluxB.seekg(i);
    }
    for (int j = 0; j < 2*deltaDiff+5; j++) {
      if (k==0) cerr << "p" << fluxA.tellg() << "." << fluxA.get() << " ";
      else cerr << "p" << fluxB.tellg() << "." << fluxB.get() << " ";
    }
    cerr << endl;
  }
}
void CompareFiles::affichageDiff(char *bufA, char *bufB, int i){
  // cerr << b2;
  cerr << "Element A " << std::bitset<8>(bufA[i-1]) << " " << std::bitset<8>(bufA[i]) << " " << std::bitset<8>(bufA[i+1]) <<endl;
  cerr << "Element B " << std::bitset<8>(bufB[i-1]) << " " << std::bitset<8>(bufB[i]) << " " << std::bitset<8>(bufB[i+1]) << endl;
}
 
 
 
 
CompareFiles::~CompareFiles()
{
  fluxA.close();
  fluxB.close();
}