Я использую iTextSharp для чтения текста из файла PDF. Однако иногда я не могу извлечь текст, потому что файл PDF содержит только изображения. Я загружаю одни и те же файлы PDF каждый день, и я хочу посмотреть, был ли PDF изменен. Если текст и дата модификации не могут быть получены, является ли контрольная сумма MD5 наиболее надежным способом определить, изменился ли файл?
Если это так, некоторые примеры кода будут оценены, потому что у меня нет большого опыта в криптографии.
Ответы:
Это очень просто с помощью System.Security.Cryptography.MD5 :
(Я считаю, что на самом деле используемую реализацию MD5 не нужно утилизировать, но я все равно, вероятно, все равно буду это делать.)
Как вы сравниваете результаты впоследствии, зависит от вас; например, вы можете преобразовать байтовый массив в base64 или сравнить байты напрямую. (Просто учтите, что массивы не переопределяются
Equals
. Использование base64 проще для правильного понимания, но немного менее эффективно, если вы действительно заинтересованы только в сравнении хешей.)Если вам нужно представить хеш в виде строки, вы можете преобразовать его в шестнадцатеричный код, используя
BitConverter
:источник
BitConverter.ToString(md5.ComputeHash(stream)).Replace("-","").ToLower();
.Replace("-", String.Empty)
, это лучший подход. Я прошел сеанс отладки в течение одного часа, потому что я получаю неправильные результаты при сравнении ввода пользователя с хэшем файла.Вот как я это делаю:
источник
using
блоков был бы полезен, потому что открытие файла более вероятно потерпит неудачу. Сбой раннего / быстрого подхода экономит ресурсы, необходимые для создания (и уничтожения) экземпляра MD5 в таких сценариях. Также вы можете опустить скобки первыхusing
и сохранить уровень отступа без потери читабельности.Я знаю, что на этот вопрос уже был дан ответ, но вот что я использую:
Где GetHash :
Вероятно, не самый лучший способ, но это может быть удобно.
источник
public static String GetHash<T>(this Stream stream) where T : HashAlgorithm, new() { StringBuilder sb = new StringBuilder(); using (T crypt = new T()) { byte[] hashBytes = crypt.ComputeHash(stream); foreach (byte bt in hashBytes) { sb.Append(bt.ToString("x2")); } } return sb.ToString(); }
Вот немного более простая версия, которую я нашел. Он читает весь файл за один раз и требует только одной
using
директивы.источник
ReadAllBytes
является то, что он загружает весь файл в один массив. Это совсем не работает для файлов размером более 2 ГБ и оказывает большое давление на ГХ даже для файлов среднего размера. Ответ Джона немного сложнее, но не страдает от этих проблем. Поэтому я предпочитаю его ответ твоему.using
s» друг за другом без первых фигурных скобок, чтоusing (var md5 = MD5.Create()) using (var stream = File.OpenRead(filename))
дает вам по одному использованию на строку без лишних отступов.using
директиву». не было действительно хорошей причины читать все в память. Более эффективный подход состоит в том, чтобы передавать данные вComputeHash
и, если возможно,using
следует использовать только, но я могу полностью понять, хотите ли вы избежать дополнительного уровня отступов.Я знаю, что опоздал на вечеринку, но выполнил тест, прежде чем на самом деле реализовать решение.
Я провел тест на встроенный класс MD5, а также md5sum.exe . В моем случае встроенный класс занял 13 секунд, где md5sum.exe тоже примерно 16-18 секунд при каждом запуске.
источник
И если вам нужно вычислить MD5, чтобы увидеть, соответствует ли он MD5 большого двоичного объекта Azure, то этот вопрос и ответ SO могут оказаться полезными: MD5-хэш большого двоичного объекта, загруженный в Azure, не совпадает с тем же файлом на локальном компьютере.
источник