Autor |
Beitrag |
veruntchik
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 01.02.11 15:36
Hallo alle zusammen,
ich weiß nicht ob es hier reinpasst aber ich versuche es.
Mein Problem besteht darin den Inhalt der Dateien in einen Schlüssel, damit man es eindeutig erkennen kann, unzuwandeln. Dazu gibt es ja schon die Methode: .GetHashCode(), die funktioniert soweit ganz gut. Was mich stört, oder was ich eher gebrauchen kann, dass von der gleichen Datei ein gleicher HashCode erzeugt wird.
Also unter gleichen Datei meine ich zwei Dateien die vielleicht in unterschiedlichen Ordnern liegen aber Last-Modified Datum das gleiche ist und die Größe ist gleich natürlich. Jetzt ist die Frage wann wird eine Datei verändert angesehen, wenn Last-Modified sich geändert hat obwohl in der Datei selbst nichts geändert wurde, sondern nur aufgemacht, gespeichert, zu gemacht, sind die dann immer noch gleich?
Und mit der Methode GetHashCode() bekomme ich keinen gleichen Hashcode der Dateien obwohl last-modified nicht geändert wurde, sondern der Name(vielleicht) ist unterschiedlich und natürlich das create-date sich geändert hat, weil es jai n einen anderen Ordner reinkopiert wurde.
Gibt es in C# andere Möglichkeiten, oder was mache ich Falsch, so einen Schlüssel aus den Inhalt der Dateien zu erstellen?
Zur Zeit gehe ich durch die Ordner Struktur(DirectoryInfo) und speichere die Dateien(FileInfo) in eine Dictionary<long key, List<string pfadListe>> die Größe der Datei als Schlüssel und deren Pfade wo sie sich befinden in eine Liste. Falls eine Datei gleiche Größe hat, wird die Liste mit zusätzlichen Pfad gefüllt. Aber das ist kein Optimum, ich muss trotzdem die Dateien auf Inhalt irgendwann überprüfen, byte für byte dauert bei 100.000den Dateien einfach viel zu lange....
Bitte um Hilfe und um Vorschläge
Vielen Dank
|
|
Greenberet
      
Beiträge: 339
Erhaltene Danke: 20
Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
|
Verfasst: Di 01.02.11 15:43
Hallo,
ich würde es mit SHA512 machen.
ComputeHash nimmt auch einen Stream als Parameter an, also kannst du dir das vorherige in ein Array einlesen sparen.
Dein Problem mit GetHashCode() ist wahrscheinlich, dass du FileInfo(oder ähnliches) verwendest.
Diese berechnen allerdings nicht den Hahscode der Datei sondern vom FileInfo Objekt. In diesem sind halt die einzelnen Werte wie Pfad,Name, LastModified, ... gespeichert und eben nicht der Inhalt.
lg
Green
|
|
veruntchik 
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 01.02.11 16:02
Vielen Dank für die Schnelle Antwort!
Ich habe es schon mit SHA512, SHA1, SHA256, usw und MD5 probier, n ur musste ich immer eine Zeichekette übergeben. Aber Danek dein Vorschlag ist sehr gut. Nur wie Schreibe ich diesen Schlüssel in die Variable strHex, weil ich bekomme ja trotzdem einen byte[] zurück!?
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| private static int GetMD5(Stream stream) { MD5 md5 = new MD5CryptoServiceProvider(); int strHex;
var HashValue = md5.ComputeHash(stream); foreach (byte b in HashValue) { strHex += ~~~~~~~~~~~~~~~~; } return strHex; } |
Ja das stimmt, ich habe mir das auch so überlegt dass gethashcode() die ganzen date-Eigenschaften mit reinnimmt in die Kodierung. Und ich habe auch extra reingeschrieben mit was ich gearbeitet habe, nämlich mit FileInfo.
Moderiert von Christian S.: C#-Tags hinzugefügt
|
|
Greenberet
      
Beiträge: 339
Erhaltene Danke: 20
Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
|
Verfasst: Di 01.02.11 16:23
Bei deinem Code fällt mir folgendes auf:
1) strHex = laut deinem Code ist es ein int. Allerdings solltest du den StringBuilder anstatt des normalen Strings verwenden( ist für solche Fälle um einiges schneller )
2) würde ich nicht MD5 nehmen sondern mindestens SHA256 oder eben SHA512. MD5 gilt schon seit langem als "geknackt"
3) um ein Byte in einen String umzuwandeln hilft dir String.Format("{0  2}", b) weiter. x = Hexadezimalzahl( 0-F ) und die 2 steht für 2 Stellen.
lg
|
|
veruntchik 
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 01.02.11 16:40
Ja okay, also SHA256. Aber ich möchte ja ein int am Ende rausbekommen, um es besser vergleichen zu können. Oder ist es sicher auch als String den Schlüssel zuspeichern? Danke für den Tipp mit MD5.
|
|
veruntchik 
Hält's aus hier
Beiträge: 13
|
Verfasst: Mi 02.02.11 09:42
Okay jetzt habe ich das soweit implementiert:
In der Main sage ich:
C#-Quelltext 1: 2:
| StreamReader myStream = new StreamReader(file, System.Text.ASCIIEncoding.ASCII); String hash = Hash.Hash.GetSHA256(myFile.BaseStream); |
file ist ein pfad als srting gespeichert.
meine Methode sieht so aus:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| private static string GetSHA256(Stream stream) { SHA256Managed SHhash = new SHA256Managed(); var HashValue = SHhash.ComputeHash(stream); StringBuilder sb = new StringBuilder(HashValue.Length); foreach (byte b in HashValue) { sb.Append(b); } return sb.ToString(); } |
es funktioniert soweit, und es kommt zu keinem Fehler. Nur egal welchen Dateipfad ich übergebe wird der gleiche "Schlüssel" erzeugt. Mache ich was falsch?, wenn ja was? Wer hat eine Idee?
Vielen Dank im Voraus
Moderiert von Kha: C#-Tags hinzugefügt
|
|
veruntchik 
Hält's aus hier
Beiträge: 13
|
Verfasst: Do 03.02.11 20:50
Danke für keinen Tipp! Und keine Hilfe.
Ich habe inzwischen selbst recherchiert, und so funktioniert's:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| string pfad ="C:\\Users\\Public\\Documents\\tcpproxy-aufgaben.pdf" ; FileStream zz = new FileStream(pfad, FileMode.Open, FileAccess.Read); StreamReader sr = new StreamReader(zz, Encoding.ASCII); byte[] data = Encoding.ASCII.GetBytes(sr.ReadToEnd()); MemoryStream memStream = new MemoryStream(data); MD5 sh = MD5.Create(); byte[] test = sh.ComputeHash(memStream);
StringBuilder sb = new StringBuilder(test.Length); foreach (byte b in test) { sb.Append(b); } |
In sb steht dann der Schlüssel der erstellt(compute) wurde.
Moderiert von Christian S.: C#-Tags hinzugefügt
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Do 03.02.11 21:39
veruntchik hat folgendes geschrieben : | Danke für keinen Tipp! Und keine Hilfe. |
Schön, wenn du dein Problem selbst lösen konntest aber, a) funktioniert dein originaler Code bei mir (weswegen wohl auch niemand Korrekturvorschläge vorbringen konnte) und b) ist deine neue Lösung Unsinn, da durch die ASCII-Dekodierung alle Bytes > 127 ignoriert werden.
_________________ >λ=
|
|
veruntchik 
Hält's aus hier
Beiträge: 13
|
Verfasst: Fr 04.02.11 12:10
Ähm, hallo,
also zu a) funktioniert das bei dir auch mit unterschiedlichen Dateien? Also von denen der Inhalt unterschiedlich ist? Weil ich brauche die genau aus dem Inhalt erzeugten Schlüssel. Und bei mir wurde immer derselbe Schlüssel erzeugt.
zu b) Ja in der Hinsicht fehlt mir die Erfahrung sowas zu sehen. Danke für den Tipp, also ohne ASCII-Dekodierung.
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Fr 04.02.11 13:47
veruntchik hat folgendes geschrieben : | also zu a) funktioniert das bei dir auch mit unterschiedlichen Dateien? |
Ja, sonst hätte ich es kaum "funktioniert" genannt  .
_________________ >λ=
|
|