Existe-t-il un moyen de calculer le hachage MD5 d'un fichier avant le téléchargement sur le serveur à l'aide de Javascript?
Bien qu'il existe implémentations de JS de l'algorithme MD5, , les anciens navigateurs ne peuvent généralement pas lire les fichiers du système de fichiers local .
Je l'ai écrit en 2009. Qu'en est-il des nouveaux navigateurs?
Avec un navigateur prenant en charge le FileAPI , vous * pouvez * lire le contenu d'un fichier - l'utilisateur doit avoir sélectionné soit avec un <input>
élément ou glisser-déposer. À compter de janvier 2013, voici comment se combinent les principaux navigateurs:
J'ai créé une bibliothèque qui implémente md5 incrémentiel afin de hacher efficacement des fichiers volumineux. En gros, vous lisez un fichier en morceaux (pour garder de la mémoire basse) et vous le hachez de manière incrémentielle. Vous avez une utilisation de base et des exemples dans le readme.
Sachez que vous avez besoin de HTML5 FileAPI, alors assurez-vous de le vérifier. Il existe un exemple complet dans le dossier de test.
il est assez facile de calculer le hachage MD5 en utilisant le fonction MD5 de CryptoJS et le HTML5 FileReader API . L'extrait de code suivant montre comment lire les données binaires et calculer le hachage MD5 à partir d'une image 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 des CSS pour voir la zone 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: File API & FileReader
J'ai testé l'exemple dans Google Chrome Version 32.
Vous devez utiliser FileAPI. Il est disponible dans les dernières versions de FF et de Chrome, mais pas dans IE9. Saisissez toute implémentation de md5 JS suggérée ci-dessus. J'ai essayé cela et je l'ai abandonné parce que JS était trop lent (minutes sur de gros fichiers image). Peut-être à nouveau si quelqu'un réécrit MD5 en utilisant des tableaux typés.
Le code ressemblerait à quelque chose comme ça:
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));
}
}
spark-md5
et Q
En supposant que vous utilisiez un navigateur moderne (prenant en charge l’API de fichier HTML5), voici comment calculer le hachage MD5 d’un fichier volumineux hachage sur des morceaux variables)
function calculateMD5Hash(file, bufferSize) {
var def = Q.defer();
var fileReader = new FileReader();
var fileSlicer = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
var hashAlgorithm = new SparkMD5();
var totalParts = Math.ceil(file.size / bufferSize);
var currentPart = 0;
var startTime = new Date().getTime();
fileReader.onload = function(e) {
currentPart += 1;
def.notify({
currentPart: currentPart,
totalParts: totalParts
});
var buffer = e.target.result;
hashAlgorithm.appendBinary(buffer);
if (currentPart < totalParts) {
processNextPart();
return;
}
def.resolve({
hashResult: hashAlgorithm.end(),
duration: new Date().getTime() - startTime
});
};
fileReader.onerror = function(e) {
def.reject(e);
};
function processNextPart() {
var start = currentPart * bufferSize;
var end = Math.min(start + bufferSize, file.size);
fileReader.readAsBinaryString(fileSlicer.call(file, start, end));
}
processNextPart();
return def.promise;
}
function calculate() {
var input = document.getElementById('file');
if (!input.files.length) {
return;
}
var file = input.files[0];
var bufferSize = Math.pow(1024, 2) * 10; // 10MB
calculateMD5Hash(file, bufferSize).then(
function(result) {
// Success
console.log(result);
},
function(err) {
// There was an error,
},
function(progress) {
// We get notified of the progress as it is executed
console.log(progress.currentPart, 'of', progress.totalParts, 'Total bytes:', progress.currentPart * bufferSize, 'of', progress.totalParts * bufferSize);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/q.js/1.4.1/q.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/spark-md5/2.0.2/spark-md5.min.js"></script>
<div>
<input type="file" id="file"/>
<input type="button" onclick="calculate();" value="Calculate" class="btn primary" />
</div>
Outre l'impossibilité d'obtenir un accès au système de fichiers dans JS, je ne ferais aucune confiance en 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 avr. 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'avais besoin de faire cela dans des applications utilisant de gros fichiers de données scientifiques, où la réception de fichiers non corrompus était la clé. Mon cas était simple, parce que les utilisateurs avaient déjà le MD5 calculé à partir de leurs outils d'analyse de données, je devais donc simplement le leur demander avec un champ de texte.
Pour obtenir le hachage de fichiers, il y a beaucoup d'options. Normalement, le problème est qu’il est très lent d’obtenir le hachage de gros fichiers.
J'ai créé une petite bibliothèque qui récupère le hachage de fichiers, avec les 64 Ko du début du fichier et les 64 Ko de la fin.
Exemple en direct: http://marcu87.github.com/hashme/ et bibliothèque: https://github.com/marcu87/hashme
Il existe quelques scripts disponibles sur Internet pour créer un hachage MD5.
Celui de webtoolkit est bon, http://www.webtoolkit.info/javascript-md5.html
Bien que, je ne pense pas qu'il aura accès au système de fichiers local car cet accès est limité.
Avec le HTML5 actuel, il devrait être possible de calculer le hachage md5 d'un fichier binaire, mais je pense que l'étape précédente consistait à convertir les données banales BlobBuilder en une chaîne. J'essaie de faire cette étape: sans succès.
Voici le code que j'ai essayé: Conversion d'un BlobBuilder en chaîne, en HTML5 Javascript