J'utilise iTextSharp pour lire le texte d'un fichier PDF. Cependant, il m'arrive de ne pas pouvoir extraire de texte, car le fichier PDF ne contient que des images. Je télécharge les mêmes fichiers PDF tous les jours et je veux voir si le PDF a été modifié. Si le texte et la date de modification ne peuvent pas être obtenus, une somme de contrôle MD5 est-elle le moyen le plus fiable de savoir si le fichier a changé?
Si c'est le cas, certains exemples de code seraient appréciés, car je n'ai pas beaucoup d'expérience avec la cryptographie.
Réponses:
C'est très simple en utilisant System.Security.Cryptography.MD5 :
(Je crois qu'en réalité l'implémentation MD5 utilisée n'a pas besoin d'être supprimée, mais je le ferais probablement quand même.)
La façon dont vous comparez les résultats par la suite dépend de vous; vous pouvez convertir le tableau d'octets en base64 par exemple, ou comparer directement les octets. (Sachez simplement que les tableaux ne remplacent pas
Equals
. L'utilisation de base64 est plus simple à obtenir, mais légèrement moins efficace si vous êtes vraiment intéressé à comparer les hachages.)Si vous devez représenter le hachage sous forme de chaîne, vous pouvez le convertir en hexadécimal en utilisant
BitConverter
:la source
BitConverter.ToString(md5.ComputeHash(stream)).Replace("-","").ToLower();
.Replace("-", String.Empty)
c'est une meilleure approche. Je suis passé par une session de débogage d'une heure parce que j'obtiens des résultats erronés lorsque je compare une entrée utilisateur au hachage de fichier.Voici comment je le fais:
la source
using
blocs serait utile, car l'ouverture d'un fichier va probablement échouer. L'approche échec précoce / rapide vous permet d'économiser les ressources nécessaires pour créer (et détruire) l'instance MD5 dans de tels scénarios. Vous pouvez également omettre les accolades de la premièreusing
et enregistrer un niveau d'indentation sans perdre en lisibilité.Je sais que cette question a déjà été répondue, mais voici ce que j'utilise:
Où GetHash :
Probablement pas la meilleure façon, mais cela peut être pratique.
la source
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(); }
Voici une version légèrement plus simple que j'ai trouvée. Il lit le fichier entier en une seule fois et ne nécessite qu'une seule
using
directive.la source
ReadAllBytes
est qu'il charge tout le fichier dans un seul tableau. Cela ne fonctionne pas du tout pour les fichiers de plus de 2 Gio et met beaucoup de pression sur le GC, même pour les fichiers de taille moyenne. La réponse de Jon n'est que légèrement plus complexe, mais ne souffre pas de ces problèmes. Je préfère donc sa réponse à la vôtre.using
s après l'autre sans les premières accoladesusing (var md5 = MD5.Create()) using (var stream = File.OpenRead(filename))
vous donne une utilisation par ligne sans indentation inutile.using
directive." n'était pas vraiment une bonne raison de tout lire en mémoire. L'approche la plus efficace consiste à diffuser les données dansComputeHash
, et si possible àusing
utiliser uniquement, mais je peux totalement comprendre si vous voulez éviter le niveau supplémentaire d'indentation.Je sais que je suis en retard pour faire la fête, mais j'ai effectué des tests avant d'implémenter la solution.
J'ai effectué un test contre la classe MD5 intégrée et également md5sum.exe . Dans mon cas, la classe intégrée a pris 13 secondes où md5sum.exe aussi environ 16-18 secondes à chaque exécution.
la source
Et si vous devez calculer le MD5 pour voir s'il correspond au MD5 d'un blob Azure, cette question et réponse SO pourraient être utiles: le hachage MD5 du blob téléchargé sur Azure ne correspond pas au même fichier sur la machine locale
la source