Benutzer mit den meisten Antworten
Hash-System funktioniert nicht

Frage
-
Hallo
Ich habe mich informiert und rausgefunden, dass der beste Weg herauszufinden, ob eine Datei verändert wurde ein Hash ist.
Allerdings ist dieser bei mir stets ungleich. Wenn ich mir die byte-Array allerdings als String anzeigen lassen sind beide exakt gleich.
Ich verwende folgende Hash Funktion
public static byte[] GetFileHash(string fileName) { HashAlgorithm sha1 = HashAlgorithm.Create(); using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) return sha1.ComputeHash(stream); }
Und hier die Abfrage
if (IncludeFiles[0].Hash != AutoCompleteAnalyzer.GetFileHash(IncludeFiles[0].Path)) MessageBox.Show(AutoCompleteAnalyzer.GetString(IncludeFiles[0].Hash) + "\n" + AutoCompleteAnalyzer.GetString(AutoCompleteAnalyzer.GetFileHash(IncludeFiles[0].Path))); else System.Media.SystemSounds.Beep.Play();
Das byte Array konvertiere ich wie folgt in einen String
public static string GetString(byte[] arr) { return Encoding.Default.GetString(arr); }
Liegt es vielleicht am Encoding, in der die Datei geschrieben ist o.ä.?
Liebe Grüße
TZDEV
Antworten
-
zu 1.)
Wenn du einen FileSystemWatcher einsetzt, brauchst du den Hash nur noch für die wirklich geänderten Dateien erzeugen und vergleichen. Das sollte effizienter sein.
Ich empfehle dir also eine Kombination aus beiden.zu 2.)
Du hast recht. Ich habe das entsprechend korrigiert.Tom Lambert - C# MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert TZDEV Samstag, 25. Oktober 2014 23:49
-
Hallo,
es sind einige Annahmen zu korrigieren:
Bevor man einen Hash berechnet, sollte man die Dateilänge prüfen - das ist schneller; denn Dateien mit unterschiedlicher Länge können nicht gleich sein.
Gute Hashfunktionen können nur Veränderungen leichter erkennbar machen. und die Information liefern, dass zwei Dateien nicht gleich sind. Umgekehrt gilt dies jedoch nicht: zwei gleiche Hash-Werte bedeuten nicht zwangsläufig, dass die Dateien gleich sind. Was mit etwas Überlegung klar sein sollte: Wenn man eine mehrere Mega- oder gar Gigabyte große Datei auf 256 oder selbst 512 Bytes zusammenfasst, können dabei Dopplungen herauskommen.
Ein Hash sollte man nicht in Zeichendaten konvertieren, um sie in eine Datei etc. zu speichern. Da darin Steuerzeichen enthalten sein können (wie z. B. CR / LF), kann dies eine spätere Verarbeitung "irritieren". Sinnvollerweise konvertiert man sie in eine hexadezimale oder Base64 - Darstellung (via System.Convert).
Byte-Arrays kann man am einfachsten via SequenceEqual vergleichen.
Gruß Elmar
- Als Antwort markiert Aleksander Chalabashiev Freitag, 31. Oktober 2014 12:19
-
Hallo,
du scheinst die Hashs (Byte-Arrays) nur durch == mit einander zu vergleichen. Dadurch wird jedoch nur geprüft ob es sich 2mal um das selbe Array handelt, die Werte spielen dabei keine Rolle.Um diese miteinander zu vergleichen, musst du die Arrays durch gehen und dann mit einander vergleichen:
var nhash = AutoCompleteAnalyzer.GetFileHash(IncludeFiles[0].Path)) MessageBox.Show(AutoCompleteAnalyzer.GetString(IncludeFiles[0].Hash; bool flag = true; for(int i=0;i<nhash.Length;++i){ if(nhash[i]!=IncludeFiles[0].Hash[i]){ flag =false; break;//Schleife verlassen } } if (flag) System.Media.SystemSounds.Beep.Play();//Hashs sind nicht gleich
Beachte bitte, das es eine sehr geringe Chance gibt, das ein Unterschied beider Dateien durch einen Hash nicht erkannt wird.
Weiterhin ist der FileSystemWatcher vielleicht interessant für dich, wenn du Dateiänderungen registrieren möchtest.
PS: Eine einfache MessageBox ist bei solchen Dingen häufig suboptimal. Setze lieber einen BreakPoint (F9) und vergleiche die Arrays manuell wärend der Quellcode angehalten ist.
Tom Lambert - C# MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Bearbeitet Tom Lambert (Koopakiller)Moderator Samstag, 25. Oktober 2014 23:31 Code korrigiert
- Als Antwort vorgeschlagen Aleksander Chalabashiev Montag, 27. Oktober 2014 08:26
- Als Antwort markiert Aleksander Chalabashiev Freitag, 31. Oktober 2014 12:18
Alle Antworten
-
Hallo,
du scheinst die Hashs (Byte-Arrays) nur durch == mit einander zu vergleichen. Dadurch wird jedoch nur geprüft ob es sich 2mal um das selbe Array handelt, die Werte spielen dabei keine Rolle.Um diese miteinander zu vergleichen, musst du die Arrays durch gehen und dann mit einander vergleichen:
var nhash = AutoCompleteAnalyzer.GetFileHash(IncludeFiles[0].Path)) MessageBox.Show(AutoCompleteAnalyzer.GetString(IncludeFiles[0].Hash; bool flag = true; for(int i=0;i<nhash.Length;++i){ if(nhash[i]!=IncludeFiles[0].Hash[i]){ flag =false; break;//Schleife verlassen } } if (flag) System.Media.SystemSounds.Beep.Play();//Hashs sind nicht gleich
Beachte bitte, das es eine sehr geringe Chance gibt, das ein Unterschied beider Dateien durch einen Hash nicht erkannt wird.
Weiterhin ist der FileSystemWatcher vielleicht interessant für dich, wenn du Dateiänderungen registrieren möchtest.
PS: Eine einfache MessageBox ist bei solchen Dingen häufig suboptimal. Setze lieber einen BreakPoint (F9) und vergleiche die Arrays manuell wärend der Quellcode angehalten ist.
Tom Lambert - C# MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Bearbeitet Tom Lambert (Koopakiller)Moderator Samstag, 25. Oktober 2014 23:31 Code korrigiert
- Als Antwort vorgeschlagen Aleksander Chalabashiev Montag, 27. Oktober 2014 08:26
- Als Antwort markiert Aleksander Chalabashiev Freitag, 31. Oktober 2014 12:18
-
Erstmal vielen Dank für die Antwort
Ich hab 2 Rückfragen
1. Wie sieht es Performancemäßig aus? Welche Methode ist in der Hinsicht besser? Hash oder FileSystemWatcher?
2. Müsste man nicht "IncludeFiles[0].Hash" ebenfalls "i" als Index geben? Sprich "IncludeFiles[0].Hash[i]"
Grüße
-
zu 1.)
Wenn du einen FileSystemWatcher einsetzt, brauchst du den Hash nur noch für die wirklich geänderten Dateien erzeugen und vergleichen. Das sollte effizienter sein.
Ich empfehle dir also eine Kombination aus beiden.zu 2.)
Du hast recht. Ich habe das entsprechend korrigiert.Tom Lambert - C# MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort markiert TZDEV Samstag, 25. Oktober 2014 23:49
-
Hallo,
es sind einige Annahmen zu korrigieren:
Bevor man einen Hash berechnet, sollte man die Dateilänge prüfen - das ist schneller; denn Dateien mit unterschiedlicher Länge können nicht gleich sein.
Gute Hashfunktionen können nur Veränderungen leichter erkennbar machen. und die Information liefern, dass zwei Dateien nicht gleich sind. Umgekehrt gilt dies jedoch nicht: zwei gleiche Hash-Werte bedeuten nicht zwangsläufig, dass die Dateien gleich sind. Was mit etwas Überlegung klar sein sollte: Wenn man eine mehrere Mega- oder gar Gigabyte große Datei auf 256 oder selbst 512 Bytes zusammenfasst, können dabei Dopplungen herauskommen.
Ein Hash sollte man nicht in Zeichendaten konvertieren, um sie in eine Datei etc. zu speichern. Da darin Steuerzeichen enthalten sein können (wie z. B. CR / LF), kann dies eine spätere Verarbeitung "irritieren". Sinnvollerweise konvertiert man sie in eine hexadezimale oder Base64 - Darstellung (via System.Convert).
Byte-Arrays kann man am einfachsten via SequenceEqual vergleichen.
Gruß Elmar
- Als Antwort markiert Aleksander Chalabashiev Freitag, 31. Oktober 2014 12:19