Como calcular o hash md5 de um arquivo usando o javascript

Existe uma maneira de calcular o hash MD5 de um arquivo antes do upload para o servidor usando JavaScript?

Embora existam implementações JS do algoritmo MD5, os navegadores mais antigos geralmente não conseguem ler arquivos do sistema de arquivos local .

Eu escrevi isso em 2009. Então, e os novos navegadores?

Com um navegador que suporta o FileAPI , você * pode * ler o conteúdo de um arquivo – o usuário deve selecioná-lo, seja com um elemento ou arrastando e soltando. A partir de janeiro de 2013, veja como os principais navegadores se comparam:

  • O FF 3.6 suporta FileReader , o FF4 suporta ainda mais funcionalidades baseadas em arquivos
  • O Chrome suporta o FileAPI desde a versão 7.0.517.41
  • O Internet Explorer 10 possui suporte parcial ao FileAPI
  • Opera 11.10 tem suporte parcial para FileAPI
  • Safari – Eu não consegui encontrar uma boa fonte oficial para isso, mas este site sugere suporte parcial de 5.1, suporte total para 6.0 . Outro artigo relata algumas inconsistências com as versões anteriores do Safari

Eu fiz uma biblioteca que implementa md5 incremental, a fim de hash grandes arquivos de forma eficiente. Basicamente você lê um arquivo em pedaços (para manter a memory baixa) e o incrementa de forma incremental. Você tem um uso básico e exemplos no readme.

Esteja ciente de que você precisa do HTML5 FileAPI, portanto, verifique-o. Há um exemplo completo na pasta de teste.

https://github.com/satazor/SparkMD5

é muito fácil calcular o hash MD5 usando a function MD5 do CryptoJS e a API FileReader do HTML5 . O trecho de código a seguir mostra como você pode ler os dados binários e calcular o hash MD5 de uma imagem que foi arrastada para o seu navegador:

 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); }; 

Eu recomendo adicionar algum CSS para ver a área Drag & Drop:

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

Mais sobre a funcionalidade Drag & Drop pode ser encontrada aqui: File API & FileReader

Eu testei a amostra no Google Chrome versão 32.

Você precisa usar o FileAPI. Está disponível no mais recente FF e Chrome, mas não no IE9. Pegue qualquer implementação md5 JS sugerida acima. Eu tentei isso e o abandonei porque o JS era muito lento (minutos em arquivos de imagem grandes). Pode revisitar se alguém reescreve o MD5 usando matrizes digitadas.

Código seria algo como isto:

 HTML:  JS (w JQuery) $("#file-dialog").change(function() { handleFiles(this.files); }); function handleFiles(files) { for (var i=0; i 

Além da impossibilidade de obter access ao sistema de arquivos no JS, eu não colocaria nenhuma confiança em uma sum de verificação gerada pelo cliente. Portanto, gerar a sum de verificação no servidor é obrigatório em qualquer caso. #: 4190 Tomalak at 14:05

Que é inútil na maioria dos casos. Você quer o MD5 computado no lado do cliente, para que você possa compará-lo com o código recalculado no lado do servidor e concluir que o upload deu errado se eles diferirem. Eu precisava fazer isso em aplicativos que trabalham com grandes arquivos de dados científicos, onde receber arquivos não corrompidos era essencial. Meus casos eram simples, porque os usuários tinham o MD5 já calculado a partir de suas ferramentas de análise de dados, então eu só precisava perguntar a eles com um campo de texto.

HTML5 + spark-md5 e Q

Supondo que você esteja usando um navegador moderno (que suporta API de arquivo HTML5), aqui está como você calcula o Hash MD5 de um arquivo grande (ele calculará o hash em partes 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); }); } 
   

Para obter o hash de arquivos, existem muitas opções. Normalmente, o problema é que é muito lento obter o hash de arquivos grandes.

Eu criei uma pequena biblioteca que pega o hash dos arquivos, com o 64kb do inicio do arquivo e o 64kb do final dele.

Exemplo ao vivo: http://marcu87.github.com/hashme/ e biblioteca: https://github.com/marcu87/hashme

Há alguns scripts lá fora na internet para criar um Hash MD5.

O de webtoolkit é bom, http://www.webtoolkit.info/javascript-md5.html

Embora não acredite que tenha access ao sistema de arquivos local, esse access é limitado.

Com o HTML5 atual, deve ser possível calcular o hash md5 de um arquivo binário, mas eu acho que o passo anterior seria converter os dados banary BlobBuilder para uma String, estou tentando fazer este passo: mas não foram bem sucedidos.

Aqui está o código que eu tentei: Convertendo um BlobBuilder em string, em Javascript HTML5

Eu não acredito que haja uma maneira em JavaScript para acessar o conteúdo de um arquivo de upload. Portanto, você não pode examinar o conteúdo do arquivo para gerar uma sum MD5.

No entanto, você pode enviar o arquivo para o servidor, que pode enviar uma sum MD5 de volta ou enviar o conteúdo do arquivo de volta … mas isso é muito trabalho e provavelmente não vale a pena para seus objectives.

Sem um plugin, você não pode acessar esses dados binários. Você deve procurar usar uma ferramenta de upload baseada em Flash. Eu tenho colegas que usaram o SWFUpload , mas não sei como obter access ao conteúdo do arquivo em si. Você pode ter que alterar o SWF para permitir isso.