125 Stimmen

Wie man md5-Hash einer Datei mit Javascript berechnen

Gibt es eine Möglichkeit, den MD5-Hash einer Datei vor dem Upload auf den Server mit Javascript zu berechnen?

3 Stimmen

Stark verwandt: [Wie generiert man eine Prüfsumme und konvertiert in 64 Bit in Javascript für sehr große Dateien, ohne dass der RAM überläuft? ]( stackoverflow.com/q/51987434/514235 )

9voto

wutzebaer Punkte 13284

Wenn sha256 ist auch in Ordnung:

  async sha256(file: File) {
    // get byte array of file
    let buffer = await file.arrayBuffer();

    // hash the message
    const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);

    // convert ArrayBuffer to Array
    const hashArray = Array.from(new Uint8Array(hashBuffer));

    // convert bytes to hex string
    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
    return hashHex;
  }

8voto

Aleksandar Totic Punkte 2509

Sie müssen die FileAPI verwenden. Es ist in den neuesten FF & Chrome verfügbar, aber nicht IE9. Nehmen Sie eine der oben vorgeschlagenen md5 JS-Implementierungen. Ich habe dies versucht und aufgegeben, weil JS zu langsam war (Minuten bei großen Bilddateien). Might revisit es, wenn jemand neu schreibt MD5 mit typisierten Arrays.

Der Code würde etwa so aussehen:

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 Stimmen

Webtoolkit MD5, auf das bendewey hinwies, schnitt viel besser ab: 16 Sekunden für eine Multi-MB-Datei: webtoolkit.info/javascript-md5.html

1 Stimmen

Ich habe es geschafft, diese arbeiten und die gleichen md5 Hash generiert (php: md5_file(...)) für Textdateien, aber Bilder geben mir unterschiedliche Ergebnisse? Liegt das an den Binärdaten oder an der Art, wie sie hochgeladen werden?

0 Stimmen

Ich bin mir ziemlich sicher, dass dieser Code nicht mit mehreren Dateien funktioniert, denn onload ist ein Callback, der reader wird die letzte Datei sein, wenn die Onload-Funktionen ausgeführt werden.

7voto

Marco Punkte 51

Abgesehen davon, dass es unmöglich ist, die Zugriff auf das Dateisystem in JS, würde ich nicht überhaupt kein Vertrauen in eine client-generierten Prüfsumme vertrauen. Also ist die Generierung der Prüfsumme auf dem Server in jedem Fall zwingend erforderlich. - Tomalak 20 Apr '09 um 14:05

Was in den meisten Fällen nutzlos ist. Sie möchten, dass der MD5-Code auf der Client-Seite berechnet wird, so dass Sie ihn mit dem auf der Server-Seite neu berechneten Code vergleichen und daraus schließen können, dass der Upload falsch gelaufen ist, wenn die Werte voneinander abweichen. Ich musste das in Anwendungen tun, die mit großen Dateien wissenschaftlicher Daten arbeiten, bei denen der Erhalt unbeschädigter Dateien entscheidend war. Meine Fälle waren einfach, denn die Benutzer hatten den MD5-Code bereits mit ihren Datenanalysetools berechnet, so dass ich ihn nur noch in einem Textfeld abfragen musste.

3voto

Marco Antonio Punkte 240

Um den Hash von Dateien zu erhalten, gibt es eine Reihe von Möglichkeiten. Normalerweise ist das Problem, dass es sehr langsam ist, den Hash von großen Dateien zu erhalten.

Ich habe eine kleine Bibliothek erstellt, die den Hash von Dateien mit den 64kb des Dateianfangs und den 64kb des Dateiendes ermittelt.

Live-Beispiel: http://marcu87.github.com/hashme/ und Bibliothek: https://github.com/marcu87/hashme

3voto

Zico Deng Punkte 515

Ich hoffe, Sie haben inzwischen eine gute Lösung gefunden. Falls nicht, ist die folgende Lösung eine ES6-Versprechen-Implementierung, die auf js-spark-md5

import SparkMD5 from 'spark-md5';

// Read in chunks of 2MB
const CHUCK_SIZE = 2097152;

/**
 * Incrementally calculate checksum of a given file based on MD5 algorithm
 */
export const checksum = (file) =>
  new Promise((resolve, reject) => {
    let currentChunk = 0;
    const chunks = Math.ceil(file.size / CHUCK_SIZE);
    const blobSlice =
      File.prototype.slice ||
      File.prototype.mozSlice ||
      File.prototype.webkitSlice;
    const spark = new SparkMD5.ArrayBuffer();
    const fileReader = new FileReader();

    const loadNext = () => {
      const start = currentChunk * CHUCK_SIZE;
      const end =
        start + CHUCK_SIZE >= file.size ? file.size : start + CHUCK_SIZE;

      // Selectively read the file and only store part of it in memory.
      // This allows client-side applications to process huge files without the need for huge memory
      fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
    };

    fileReader.onload = e => {
      spark.append(e.target.result);
      currentChunk++;

      if (currentChunk < chunks) loadNext();
      else resolve(spark.end());
    };

    fileReader.onerror = () => {
      return reject('Calculating file checksum failed');
    };

    loadNext();
  });

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X