Estoy usando iTextSharp para leer el texto de un archivo PDF. Sin embargo, hay veces que no puedo extraer texto, porque el archivo PDF solo contiene imágenes. Descargo los mismos archivos PDF todos los días, y quiero ver si el PDF ha sido modificado. Si no se puede obtener el texto y la fecha de modificación, ¿es la suma de verificación MD5 la forma más confiable de saber si el archivo ha cambiado?
Si es así, se agradecerían algunos ejemplos de código, porque no tengo mucha experiencia con la criptografía.
Respuestas:
Es muy simple usar System.Security.Cryptography.MD5 :
(Creo que en realidad la implementación de MD5 utilizada no necesita ser eliminada, pero probablemente todavía lo haría de todos modos).
La forma de comparar los resultados después depende de usted; puede convertir la matriz de bytes a base64, por ejemplo, o comparar los bytes directamente. (Solo tenga en cuenta que las matrices no se anulan
Equals
. Usar base64 es más sencillo, pero un poco menos eficiente si realmente solo está interesado en comparar los hashes).Si necesita representar el hash como una cadena, puede convertirlo a hexadecimal usando
BitConverter
:fuente
BitConverter.ToString(md5.ComputeHash(stream)).Replace("-","").ToLower();
.Replace("-", String.Empty)
es un mejor enfoque. Pasé por una sesión de depuración de una hora porque obtengo resultados incorrectos al comparar la entrada de un usuario con el hash del archivo.Así es como lo hago:
fuente
using
bloques sería útil, porque abrir un archivo probablemente fallará. El enfoque de falla temprana / rápida le ahorra los recursos necesarios para crear (y destruir) la instancia MD5 en tales escenarios. También puede omitir las llaves del primerousing
y guardar un nivel de sangría sin perder legibilidad.Sé que esta pregunta ya fue respondida, pero esto es lo que uso:
Donde GetHash :
Probablemente no sea la mejor manera, pero puede ser útil.
fuente
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(); }
Aquí hay una versión un poco más simple que encontré. Lee todo el archivo de una vez y solo requiere una sola
using
directiva.fuente
ReadAllBytes
es que carga todo el archivo en una sola matriz. Eso no funciona en absoluto para archivos de más de 2 GiB y ejerce mucha presión sobre el GC, incluso para archivos de tamaño mediano. La respuesta de Jon es solo un poco más compleja, pero no sufre estos problemas. Así que prefiero su respuesta sobre la tuya.using
s una detrás de la otra sin las primeras llavesusing (var md5 = MD5.Create()) using (var stream = File.OpenRead(filename))
le da una usando por línea sin sangría innecesaria.using
directiva". No era realmente una buena razón para leer todo en la memoria. El enfoque más efectivo es transmitir los datosComputeHash
y, si es posibleusing
, solo debe usarse, pero puedo entender por completo si desea evitar el nivel adicional de sangría.Sé que llego tarde a la fiesta, pero realicé la prueba antes de implementar la solución.
Realicé la prueba contra la clase MD5 incorporada y también md5sum.exe . En mi caso, la clase incorporada tomó 13 segundos donde md5sum.exe también alrededor de 16-18 segundos en cada ejecución.
fuente
Y si necesita calcular el MD5 para ver si coincide con el MD5 de un blob de Azure, entonces esta pregunta y respuesta SO podría ser útil: el hash MD5 del blob cargado en Azure no coincide con el mismo archivo en la máquina local
fuente