none
Hash-System funktioniert nicht RRS feed

  • 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);
    }

    Bild von der MessageBox

    Liegt es vielleicht am Encoding, in der die Datei geschrieben ist o.ä.?

    Liebe Grüße

    TZDEV

    Samstag, 25. Oktober 2014 22:37

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
    Samstag, 25. Oktober 2014 23:36
    Moderator
  • 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

    Sonntag, 26. Oktober 2014 07:49
    Beantworter
  • 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


    Samstag, 25. Oktober 2014 22:47
    Moderator

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


    Samstag, 25. Oktober 2014 22:47
    Moderator
  • 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

    Samstag, 25. Oktober 2014 23:30
  • 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
    Samstag, 25. Oktober 2014 23:36
    Moderator
  • 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

    Sonntag, 26. Oktober 2014 07:49
    Beantworter