it-swarm.com.de

Berechnen Sie die MD5-Prüfsumme für eine Datei

Ich benutze iTextSharp , um den Text aus einer PDF Datei zu lesen. Manchmal kann ich jedoch keinen Text extrahieren, da die Datei PDF nur Bilder enthält. Ich lade jeden Tag die gleichen PDF Dateien herunter und möchte sehen, ob die PDF geändert wurden. Wenn der Text und das Änderungsdatum nicht abgerufen werden können, ist eine MD5 Prüfsumme die zuverlässigste Methode, um festzustellen, ob sich die Datei geändert hat?

Wenn ja, wären einige Codebeispiele willkommen, da ich nicht viel Erfahrung mit Kryptografie habe.

307
broke

Es ist sehr einfach mit System.Security.Cryptography.MD5 :

using (var md5 = MD5.Create())
{
    using (var stream = File.OpenRead(filename))
    {
        return md5.ComputeHash(stream);
    }
}

(Ich glaube, dass tatsächlich die verwendete MD5-Implementierung nicht entsorgt werden muss, aber ich würde es wahrscheinlich trotzdem tun.)

Wie Sie die Ergebnisse anschließend vergleichen, liegt bei Ihnen. Sie können das Byte-Array beispielsweise in base64 konvertieren oder die Bytes direkt vergleichen. (Beachten Sie jedoch, dass Arrays Equals nicht überschreiben. Die Verwendung von base64 ist einfacher, aber etwas weniger effizient, wenn Sie wirklich nur die Hashes vergleichen möchten.)

Wenn Sie den Hash als String darstellen müssen, können Sie ihn mit BitConverter in Hex konvertieren:

static string CalculateMD5(string filename)
{
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(filename))
        {
            var hash = md5.ComputeHash(stream);
            return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
        }
    }
}
701
Jon Skeet

So mache ich es:

using System.IO;
using System.Security.Cryptography;

public string checkMD5(string filename)
{
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(filename))
        {
            return Encoding.Default.GetString(md5.ComputeHash(stream));
        }
    }
}
65
BoliBerrys

Ich weiß, dass diese Frage bereits beantwortet wurde, aber ich verwende Folgendes:

using (FileStream fStream = File.OpenRead(filename)) {
    return GetHash<MD5>(fStream)
}

Wobei GetHash:

public static String GetHash<T>(Stream stream) where T : HashAlgorithm {
    StringBuilder sb = new StringBuilder();

    MethodInfo create = typeof(T).GetMethod("Create", new Type[] {});
    using (T crypt = (T) create.Invoke(null, null)) {
        byte[] hashBytes = crypt.ComputeHash(stream);
        foreach (byte bt in hashBytes) {
            sb.Append(bt.ToString("x2"));
        }
    }
    return sb.ToString();
}

Wahrscheinlich nicht der beste Weg, aber es kann praktisch sein.

7
Badaro Jr.

Und wenn Sie das MD5 berechnen müssen, um festzustellen, ob es mit dem MD5 eines Azure-Blobs übereinstimmt, kann diese SO Frage und Antwort hilfreich sein: Der auf Azure hochgeladene MD5-Blob-Hash stimmt nicht mit derselben Datei überein auf lokaler Maschine

3
Manfred

Hier ist eine etwas einfachere Version, die ich gefunden habe. Es liest die gesamte Datei auf einmal und benötigt nur eine einzige Anweisung using.

byte[] ComputeHash(string filePath)
{
    using (var md5 = MD5.Create())
    {
        return md5.ComputeHash(File.ReadAllBytes(filePath));
    }
}
2
Ashley Davis

Ich weiß, dass ich zu spät zur Party komme, aber vor der eigentlichen Implementierung der Lösung einen Test durchgeführt habe.

Ich habe einen Test gegen die eingebaute MD5-Klasse und auch md5sum.exe durchgeführt. In meinem Fall dauerte die eingebaute Klasse 13 Sekunden, wobei md5sum.exe bei jedem Durchlauf ebenfalls 16-18 Sekunden benötigte.

    DateTime current = DateTime.Now;
    string file = @"C:\text.iso";//It's 2.5 Gb file
    string output;
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(file))
        {
            byte[] checksum = md5.ComputeHash(stream);
            output = BitConverter.ToString(checksum).Replace("-", String.Empty).ToLower();
            Console.WriteLine("Total seconds : " + (DateTime.Now - current).TotalSeconds.ToString() + " " + output);
        }
    }
0