Вычислить контрольную сумму MD5 для файла

Я использую iTextSharp для чтения текста из файла PDF. Однако есть моменты, когда я не могу извлечь текст, потому что файл PDF содержит только изображения. Я загружаю те же файлы PDF каждый день, и я хочу посмотреть, был ли PDF файл изменен. Если текст и дата модификации не могут быть получены, является MD5 контрольной суммой наиболее надежным способом узнать, изменился ли файл?

Если это так, некоторые образцы кода будут оценены, потому что у меня нет большого опыта в криптографии.

Ответ 1

Это очень просто, используя System.Security.Cryptography.MD5:

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

(Я считаю, что фактически используемая реализация MD5 не должна быть утилизирована, но я все равно все равно сделаю это.)

Как вы сравниваете результаты после этого, зависит от вас; вы можете преобразовать массив байтов в base64, например, или сравнить байты напрямую. (Просто имейте в виду, что массивы не переопределяют Equals. Использование base64 проще для правильного, но немного менее эффективного, если вы действительно заинтересованы только в сравнении хэшей.)

Если вам нужно представить хэш как строку, вы можете преобразовать его в hex с помощью BitConverter:

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

Ответ 2

Вот как я это делаю:

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

Ответ 3

Я знаю, что на этот вопрос уже был дан ответ, но это то, что я использую:

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

Где 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();
}

Возможно, это не самый лучший способ, но это может быть удобно.

Ответ 4

Вот немного более простая версия, которую я нашел. Он читает весь файл за один раз и требует только одну директиву using.

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