Possible de calculer MD5 (ou autres) de hachage avec tampon de lecture?
J'ai besoin de calculer les sommes de très gros fichiers (gigaoctets). Ceci peut être accompli en utilisant la méthode suivante:
private byte[] calcHash(string file)
{
System.Security.Cryptography.HashAlgorithm ha = System.Security.Cryptography.MD5.Create();
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
byte[] hash = ha.ComputeHash(fs);
fs.Close();
return hash;
}
Toutefois, les fichiers sont normalement écrites à l'avance dans un buffer manière (par exemple écrire de 32 mo est à la fois). Je suis tellement convaincu que j'ai vu un remplacement d'une fonction de hachage qui m'a permis de calculer un MD5 (ou autres) de hachage en même temps que l'écriture, c'est à dire: le calcul de la valeur de hachage d'un tampon, puis l'alimentation de celle qui résulte de hachage dans la prochaine itération.
Quelque chose comme ceci: (pseudo-ish)
byte [] hash = new byte [] { 0,0,0,0,0,0,0,0 };
while(!eof)
{
buffer = readFromSourceFile();
writefile(buffer);
hash = calchash(buffer, hash);
}
de hachage est maintenant sililar à ce qui allait être fait en exécutant la calcHash de la fonction sur l'ensemble du fichier.
Maintenant, je ne peux pas trouver des remplacements comme ça dans the.Net 3.5 Cadre, suis-je en train de rêver ? A il n'a jamais existé, ou suis-je juste moche à la recherche ? La raison de faire à la fois d'écriture et de calcul de checksum à la fois parce qu'il fait sens en raison de fichiers de taille importante.
Vous devez vous connecter pour publier un commentaire.
Vous utilisez le
TransformBlock
etTransformFinalBlock
méthodes pour traiter les données en blocs.Remarque: Il fonctionne (au moins avec le MD5 fournisseur) pour envoyer tous les blocs de
TransformBlock
et puis envoyer un bloc vide àTransformFinalBlock
pour finaliser le processus.block
parnull
dans l'appel à TransformBlock; vous n'avez pas vraiment envie de tout copier à se produire; le paramètre de sortie n'est pas réellement faire quelque chose à l'égard de hachage.J'aime la réponse ci-dessus, mais par souci d'exhaustivité, et plus général de la solution, reportez-vous à la
CryptoStream
classe. Si vous êtes déjà en cours de traitement des flux, il est facile pour envelopper votre flux dans uneCryptoStream
, le passage d'unHashAlgorithm
comme leICryptoTransform
paramètre.Vous pourriez avoir à fermer le flux de données avant d'obtenir le hash (de sorte que le
HashAlgorithm
sait c'est fait).Semble que vous pouvez utiliser
TransformBlock
/TransformFinalBlock
, comme le montre cet exemple: Afficher la progression des mises à jour lorsque le hachage des fichiers volumineuxAlgorithmes de hachage sont attendus pour gérer cette situation et sont généralement mis en œuvre avec 3 fonctions:
hash_init()
- Disant à allouer des ressources et de commencer le hachage.hash_update()
- Disant avec les nouvelles données qu'il arrive.hash_final()
- Effectuer le calcul et gratuit de ressources.Regarder http://www.openssl.org/docs/crypto/md5.html ou http://www.openssl.org/docs/crypto/sha.html pour de bon, la norme des exemples en C, j'en suis sûr, il existe des bibliothèques pour votre plate-forme.
J'ai juste eu à faire quelque chose de similaire, mais je voulais lire le fichier en mode asynchrone. C'est à l'aide de TransformBlock et TransformFinalBlock et me donne des réponses cohérentes avec Azure, donc je pense que c'est correct!
ArrayPool
?ArrayPool
, besoin d'installer le paquetSystem.Buffers
.