Bonjour à toutes et à tous,
Comment faire pour comparer octet par octet deux fichiers binaires ?
Cordialement.
Pierre
Bonjour à toutes et à tous,
Comment faire pour comparer octet par octet deux fichiers binaires ?
Cordialement.
Pierre
Bonjour,
Que s'agit-il d'en faire ? Vérifier l'identité, avoir le différentiel, etc. ?
Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
. Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !
Salut ceci répondra à ta question
A+
- "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
- "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
- "La simplicité est la sophistication suprême" - Léonard De Vinci
- "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei
Mes projets sur Github - Blog - Site DVP
Juste voir s'ils sont identiques ou non, mais ils font de l'ordre de 20 Mo.
J'ai fait un petit programme qui fonctionne, mais pour comparer mes deux fichiers de 20 Mo chacun, il faut plusieurs minutes.
Je vais voir la procédure que me propose BeanzMaster.
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 procedure TForm1.btnFchBin1Click(Sender: TObject); begin if OpenDialog1.Execute then begin FchBin1:= TFileStream.Create(OpenDialog1.FileName, fmOpenRead); L1:= FchBin1.Size; LgFch1.Text:= IntToStr(L1); end; end; procedure TForm1.btnFchBin2Click(Sender: TObject); begin if OpenDialog1.Execute then begin FchBin2:= TFileStream.Create(OpenDialog1.FileName, fmOpenRead); L2:= FchBin1.Size; LgFch2.Text:= IntToStr(L2); end; end; procedure TForm1.ComparerClick(Sender: TObject); var i: Integer; begin if L1 = L2 then begin for i:= 0 to L1-1 do if FchBin1.ReadByte = FchBin2.ReadByte then begin Resultat.Text:= 'Différents'; Break; end; Resultat.Text:= 'Identiques'; end else Resultat.Text:= 'Différents'; end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin FchBin1.Free; FchBin2.Free; end;
Cordialement.
Pierre
Bonjour !
Le problème a été examiné dans ces deux discussions :
https://www.developpez.net/forums/d1...-sous-windows/
https://www.developpez.net/forums/d1...s/#post9044229
Voici deux fichiers qui sont identiques quand on les passe dans un logiciel de comparaison de texte mais qui sont différents lorsqu'on les passe dans un logiciel de comparaison hexadécimal.
NOTA : Je pense qu'à l'origine, ce sont des fichiers binaires.
Cordialement.
Pierre
Il s'agit de fichiers binaires (au moins pour les codages que je connais (ansi/OEM/Mac/EBCDIC) (il y a 11 différences). Avec quel outils les compares tu comme des textes parce que mon éditeur de texte les considère comme binaires?
L'application DIFF de Microsoft les considère comme binaires et différents>diff 560.txt 560_mod.txt
Binary files 560.txt and 560_mod.txt differ
PSPAD (lien)
diff existe depuis au moins dos 3 (donc longtemps...) (edit 20H43)
Salut Pierre,
Un calcul de checksum CRC32 par exemple peut suffire pour savoir s'ils sont identiques, sinon il faut parcourir les octets un à un et les comparer.
Pour info voilà une méthode dont je me sers pour savoir si des données sont au format texte ou pas. Elle ne gère pas tout, mais fonctionne dans une grande majorité des cas :
A+
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 Function TBZStringList.CheckDataIsText(Const aBuf: Pointer): Boolean; Var Buf: String; i, Len: Integer; NewLine: Boolean; p: PChar; ZeroAllowed: Boolean; Begin //ShowMessage('Verification DataIsText'); Result := False; Len := 1024; SetLength(Buf, Len + 1); Len := SizeOf(aBuf); If Len > 0 Then Begin Buf[Len + 1] := #0; p := PChar(aBuf); ZeroAllowed := False; If (p[0] = #$EF) And (p[1] = #$BB) And (p[2] = #$BF) Then Begin //ShowMessage('UTF-8 BOM (Byte Order Mark)'); Inc(p, 3); End Else If (p[0] = #$FF) And (p[1] = #$FE) Then Begin //ShowMessage('ucs-2le BOM FF FE'); Inc(p, 2); ZeroAllowed := True; End Else If (p[0] = #$FE) And (p[1] = #$FF) Then Begin //ShowMessage('ucs-2be BOM FE FF'); Inc(p, 2); ZeroAllowed := True; End Else Begin ZeroAllowed := True; //ShowMessage('Ansi String'); End; NewLine := False; i := 0; While (i < len) Do Begin Case p^ Of #0: If p - PChar(Buf) >= Len Then break Else If Not ZeroAllowed Then Begin Raise Exception.Create('Erreur DataIsText ZeroAllowed'); exit; End; // #12: form feed // #26: end of file #1..#7, #11, #14..#25, #27..#31: Begin Raise Exception.Create('Erreur DataIsText Invalide CHAR : ' + IntToStr(Ord(p^)) + ' pos : ' + IntToStr(i)); exit; End; #10, #13: NewLine := True; End; Inc(p); Inc(i); End; If NewLine Or (Len < 1024) Then Result := True Else Raise Exception.Create('Erreur DataIsText Longueur invalide'); End; End;
Jérôme
EDIT : Tes 2 fichiers sont bien des binaires et différents. Notepad++ les voit également comme tels.
- "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
- "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
- "La simplicité est la sophistication suprême" - Léonard De Vinci
- "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei
Mes projets sur Github - Blog - Site DVP
Cette fonction CompareStreams n'est pas complète. Si les flux sont de tailles différentes, elle contrôle simplement que le début du plus grand correspond au plus petit. Il faudrait au moins un Inc(DifferenceCount) dans ce cas.
Le taux de différences est également simpliste. Dans un cas extrême avec un flux de 1 octet et un autre de 100 et le premier octet différent, la fonction retourne 1% de différence alors qu'elle est de 100% !
Et s'il manque juste un octet dans un des flux, le taux variera en fonction de la position de cette différence.
Comparer deux zones mémoires peut se faire à l'aide de CompareMem. Rechercher le nombre de différences est autrement plus complexe![]()
Soit dit en passant, sous Windows, on peut utiliser les commandes comp et fc.
Code X : 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 C:\Roland>help comp Compare le contenu de deux fichiers ou ensembles de fichiers. COMP [data1] [data2] [/D] [/A] [/L] [/N=chiffre] [/C] [/OFF[LINE]] [/M] data1 Spécifie l'emplacement et le(s) nom(s) du (des) premier(s) fichier(s) à comparer. data2 Spécifie l'emplacement et le(s) nom(s) des deuxièmes fichiers à comparer. /D Affiche les différences au format décimal. /A Affiche les différences en caractères ASCII. /L Affiche les numéros de ligne pour les différences. /N=chiffre Compare uniquement le premier nombre de lignes spécifié dans chaque fichier. /C Ignore le cas des lettres ASCII lors de la comparaison de fichiers. /OFF[LINE] N'ignorez pas les fichiers avec un ensemble d'attributs hors connexion. /M Ne pas demander de comparer d'autres fichiers. Pour comparer des ensembles de fichiers, utilisez des caractères génériques dans les paramètres data1 et data2.
Code X : 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 C:\Roland>help fc Compare deux fichiers ou ensembles de fichiers et affiche les différences entre eux. FC [/A] [/C] [/L] [/LBn] [/N][/OFF[LINE]][/T] [/U] [/W] [/nnnn] [lect1:][chemin1]fichier1 [lect2:][chemin2]fichier2 FC /B [lect1:][chemin1]fichier1 [lect2:][chemin2]fichier2 /A Affiche la 1ère et dernière ligne de chaque ensemble de différences. /B Effectue une comparaison binaire. /C Ignore la casse. /L Compare les fichiers en tant que texte ASCII. /LBn Définit le nombre maximal de différences consécutives comme égal au nombre de lignes spécifié. /N Affiche les numéros de ligne pour une comparaison ASCII. /OFF[LINE] Ne pas ignorer les fichiers dont l’attribut hors connexion a été réglé. /T Ne convertit pas les tabulations en espaces. /U Compare les fichiers en tant que fichiers texte UNICODE. /W Comprime les blancs (tabulations et espaces) pour la comparaison. /nnnn Spécifie le nombre de lignes consécutives qui doivent correspondre après une différence. [lect1:][chemin1]fichier1 Spécifie le premier fichier ou ensemble de fichiers à comparer. [lect2:][chemin2]fichier2 Spécifie le second fichier ou ensemble de fichiers à comparer.
Je me suis amusé à "améliorer" cette procédure :
Cordialement.
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 unit FntrBase; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, Buttons, Math; type { TForm1 } TForm1 = class(TForm) BitBtn1: TBitBtn; Comparer: TButton; MemoDiff: TMemo; OpenDialog1: TOpenDialog; rdgAffichage: TRadioGroup; procedure ComparerClick(Sender: TObject); procedure rdgAffichageClick(Sender: TObject); private { private declarations } Frmt: String; function CompareStreams(Stream1, Stream2: TStream): Extended; public { public declarations } end; var Form1: TForm1; implementation {$R *.lfm} function TForm1.CompareStreams(Stream1, Stream2: TStream): Extended; type TCompareBuffer = array[0..8191] of Byte; const szCompareBuffer = SizeOf(TCompareBuffer); // store the buffer's size var Buffer1: TCompareBuffer; // buffer variables, one for each stream Buffer2: TCompareBuffer; ReadBytes1: Integer; // variables that will store the actual read bytes from streams ReadBytes2: Integer; DifferenceCount: Int64; // declare a variable that will store the number of different bytes in streams Index: Integer; // loop variable MaxCount: Integer; // max difference check loop's per buffer IndX : Integer; // Position dans le flux begin Stream1.Position := 0; // set stream position to 0 Stream2.Position := 0; DifferenceCount := 0; // initialize difference count IndX:= 0; while True do begin // start a loop ReadBytes1 := Stream1.Read(Buffer1, szCompareBuffer); // read from both streams ReadBytes2 := Stream2.Read(Buffer2, szCompareBuffer); MaxCount := Min(ReadBytes1, ReadBytes2); // set the max count to the smaller value of read bytes for Index := 0 to MaxCount -1 do // check differences byte by byte if Buffer1[Index] <> Buffer2[Index] then // difference found! increment DifferenceCount variable begin Inc(DifferenceCount); MemoDiff.Lines.Add(Format(Frmt, [DifferenceCount, IndX+Index, Buffer1[Index], Buffer2[Index]])); end; // if the number of read bytes from Stream1 is different than the // number of read bytes from Stream or we haven't read any bytes from // a stream, then break the loop, we're done comparing if (ReadBytes1 <> ReadBytes2) or (ReadBytes1 = 0) or (ReadBytes2 = 0) then begin if (ReadBytes1 <> ReadBytes2) then begin MemoDiff.Lines.Add('Fichiers de tailles différentes'); DifferenceCount:= -1; end; Break; end; Inc(IndX, ReadBytes1); end; // while True do begin if DifferenceCount = 0 then MemoDiff.Lines.Add('Fichiers identiques'); Result := (DifferenceCount * 100) / Max(Stream1.Size, Stream2.Size); // return the number of differences end; { TForm1 } procedure TForm1.ComparerClick(Sender: TObject); var Stream1: TFileStream; Stream2: TFileStream; Differences: Extended; begin Differences := 0.0000; if OpenDialog1.Execute and (OpenDialog1.Files.Count = 2) then try MemoDiff.Clear; rdgAffichageClick(Sender); Stream1 := TFileStream.Create(OpenDialog1.Files[0], fmOpenRead); Stream2 := TFileStream.Create(OpenDialog1.Files[1], fmOpenRead); Differences := CompareStreams(Stream1, Stream2); finally FreeAndNil(Stream1); FreeAndNil(Stream2); end; // ShowMessageFmt('%.4f', [Differences]); end; procedure TForm1.rdgAffichageClick(Sender: TObject); begin if rdgAffichage.ItemIndex = 0 then Frmt:= '%3d %8d %3d %3d' else Frmt:= '%3x %8x %3x %3x'; end; end.
Pierre
Lorsque je charge mes fichiers dans Notepad++, il les voit comme des fichiers ??? Si j'utilise alors le menu "Compléments -> Compare -> Compare", le résultat affiché est "Files match".
Si je fais un affichage hexadécimal de ces deux fichiers par "Compléments -> HEX Editor -> View in HEX" et que je fais de nouveau "Compléments -> Compare -> Compare", le résultat est "Nothing to compare".
NOTA : Je suis sous Windows XP 32 bits et Notepad++ V 7.5.6
Re NOTA : je viens de commander un nouveau PC à monter 64 bits avec Windows 10 et j'installerai Ubunutu 18.0.4 LTS (j'espère arriver à tout cela)
Cordialement.
Pierre
Voila comment chez moi NotePad++ voit tes 2 fichiers
en mode comparaison
et enfin en mode Hexadecimal avec comparaison (Complément ou modules d'extensions -->Hex editor --> Compare HEX)
Ma version de notepad++
![]()
- "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
- "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
- "La simplicité est la sophistication suprême" - Léonard De Vinci
- "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei
Mes projets sur Github - Blog - Site DVP
Partager