125 votes

Comment calculer le hachage md5 d'un fichier en utilisant javascript

Existe-t-il un moyen de calculer le hachage MD5 d'un fichier avant le téléchargement vers le serveur en utilisant Javascript ?

3 votes

Fortement lié : [Comment générer une somme de contrôle et convertir en 64 bits en Javascript pour les très gros fichiers sans déborder de la RAM ? ]( stackoverflow.com/q/51987434/514235 )

107voto

Paul Dixon Points 122033

Bien qu'il y ait Implémentations JS de l'algorithme MD5, les anciens navigateurs sont généralement incapables de lire les fichiers du système de fichiers local. .

J'ai écrit ça en 2009. Qu'en est-il des nouveaux navigateurs ?

Avec un navigateur qui supporte le FileAPI vous peut lire le contenu d'un fichier - l'utilisateur doit l'avoir sélectionné, soit avec une <input> ou par glisser-déposer. En janvier 2013, voici comment les principaux navigateurs se positionnent :

Comment ?

Voir le réponse ci-dessous par Benny Neugebauer qui utilise le Fonction MD5 de CryptoJS

33 votes

Outre l'impossibilité d'obtenir l'accès au système de fichiers en JS, je ne ferais pas du tout confiance à une somme de contrôle générée par le client. La génération de la somme de contrôle sur le serveur est donc obligatoire dans tous les cas.

7 votes

@Tomalak Il est également obligatoire de le faire sur le client si vous ne voulez le télécharger que s'il est différent de ce que vous avez déjà.

3 votes

John Eh bien, ma déclaration n'exclut pas cette possibilité. Les contrôles côté client sont strictement destinés à faciliter la tâche de l'utilisateur (et sont donc plus ou moins facultatifs, selon le degré de commodité souhaité). En revanche, les contrôles côté serveur sont obligatoires.

34voto

satazor Points 171

J'ai créé une bibliothèque qui implémente le md5 incrémental afin de hacher efficacement les gros fichiers. Fondamentalement, vous lisez un fichier en morceaux (pour garder la mémoire basse) et le hacher de façon incrémentale. Vous trouverez l'utilisation de base et des exemples dans le fichier readme.

Soyez conscient que vous avez besoin de HTML5 FileAPI, donc assurez-vous de le vérifier. Il y a un exemple complet dans le dossier de test.

https://github.com/satazor/SparkMD5

0 votes

@Biswa voici ma mise en œuvre. gist.github.com/marlocorridor/3e6484ae5a646bd7c625

1 votes

Hé, ça marche bien ! J'ai essayé CryptoJS et je n'ai jamais pu obtenir un MD5 précis pour une raison quelconque, ceci fonctionne comme un charme ! Des plans pour sha256 ? @satazor

0 votes

@cameck, la bibliothèque est bonne. Cependant, je l'ai essayée aujourd'hui et il semble qu'il y ait un problème avec l'option .end() méthode. Si vous appelez cette méthode à nouveau, elle donnera un résultat erroné les fois suivantes. Parce que .end() appelle .reset() en interne. C'est un désastre en matière de codage et ce n'est pas bon pour la rédaction des bibliothèques.

34voto

Benny Neugebauer Points 5393

Il est assez facile de calculer le hachage MD5 en utilisant la fonction Fonction MD5 de CryptoJS y el API HTML5 FileReader . L'extrait de code suivant montre comment vous pouvez lire les données binaires et calculer le hachage MD5 d'une image qui a été glissée dans votre navigateur :

var holder = document.getElementById('holder');

holder.ondragover = function() {
  return false;
};

holder.ondragend = function() {
  return false;
};

holder.ondrop = function(event) {
  event.preventDefault();

  var file = event.dataTransfer.files[0];
  var reader = new FileReader();

  reader.onload = function(event) {
    var binary = event.target.result;
    var md5 = CryptoJS.MD5(binary).toString();
    console.log(md5);
  };

  reader.readAsBinaryString(file);
};

Je recommande d'ajouter quelques CSS pour voir la zone de Drag & Drop :

#holder {
  border: 10px dashed #ccc;
  width: 300px;
  height: 300px;
}

#holder.hover {
  border: 10px dashed #333;
}

Pour en savoir plus sur la fonctionnalité "glisser-déposer", cliquez ici : API de fichiers et lecteur de fichiers

J'ai testé l'échantillon dans Google Chrome Version 32.

2 votes

Le problème est que readAsBinaryString() n'a pas été normalisé et n'est pas pris en charge par Internet Explorer. Je ne l'ai pas testé dans Edge, mais même IE11 ne le supporte pas.

0 votes

@user25163 Internet Explorer (et Opera Mini) semblent être les seuls navigateurs modernes à ne pas supporter readAsBinaryString() : caniuse.com/#feat=filereader - Microsoft Edge le prend en charge.

0 votes

Merci pour l'information concernant MS Edge ! Je travaille pour une entreprise. Et vous savez, que les clients utilisent souvent de vieux logiciels et combien il est difficile de les convaincre de mettre à jour leurs logiciels. Je voulais juste souligner qu'il faut être prudent en utilisant MS Edge. readAsBinaryString() car il n'est pas pris en charge par les anciens navigateurs. Une alternative que j'ai trouvée est SparkMD5. Elle utilise également l'API FileReader mais la méthode readAsArrayBuffer qui est supporté par IE. Et il peut gérer des fichiers énormes en les lisant par morceaux.

8voto

Aleksandar Totic Points 1605

Vous devez utiliser FileAPI. Il est disponible dans les derniers FF et Chrome, mais pas dans IE9. Prenez n'importe quelle implémentation JS md5 suggérée ci-dessus. J'ai essayé cela et l'ai abandonné parce que JS était trop lent (minutes sur les gros fichiers d'image). Je pourrais y revenir si quelqu'un réécrit MD5 en utilisant des tableaux typés.

Le code ressemblerait à quelque chose comme ceci :

HTML:     
<input type="file" id="file-dialog" multiple="true" accept="image/*">

JS (w JQuery)

$("#file-dialog").change(function() {
  handleFiles(this.files);
});

function handleFiles(files) {
    for (var i=0; i<files.length; i++) {
        var reader = new FileReader();
        reader.onload = function() {
        var md5 = binl_md5(reader.result, reader.result.length);
            console.log("MD5 is " + md5);
        };
        reader.onerror = function() {
            console.error("Could not read the file");
        };
        reader.readAsBinaryString(files.item(i));
     }
 }

0 votes

Le MD5 de Webtoolkit indiqué par bendewey a donné de bien meilleurs résultats, 16 secondes pour un fichier de plusieurs Mo : webtoolkit.info/javascript-md5.html

1 votes

J'ai réussi à le faire fonctionner et le même hachage md5 est généré (php : md5_file(...)) pour les fichiers texte mais les images me donnent des résultats différents ? Est-ce que cela a quelque chose à voir avec les données binaires ou la façon dont elles sont téléchargées ?

0 votes

Je suis presque sûr que ce code ne fonctionne pas avec plusieurs fichiers, parce que onload est un callback, le fichier reader sera le dernier fichier au moment de l'exécution des fonctions onload.

7voto

Marco Points 21

Outre l'impossibilité d'obtenir accès au système de fichiers en JS, je n'aurais pas pas du tout confiance dans une somme de contrôle générée par le client. Donc générer la somme de contrôle sur le serveur est obligatoire dans tous les cas. - Tomalak 20 avril '09 à 14:05

Ce qui est inutile dans la plupart des cas. Vous voulez que le MD5 soit calculé côté client, afin de pouvoir le comparer avec le code recalculé côté serveur et conclure que le téléchargement s'est mal passé s'ils diffèrent. J'ai eu besoin de faire cela dans des applications travaillant avec de gros fichiers de données scientifiques, où la réception de fichiers non corrompus était essentielle. Mon cas était simple, car les utilisateurs avaient déjà calculé le MD5 à partir de leurs outils d'analyse de données, il me suffisait donc de le leur demander dans un champ de texte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X