web-dev-qa-db-de.com

Abrufen des Hash einer Datei mithilfe der Stream-Funktionen des Kryptomoduls (dh ohne hash.update und hash.digest)

Das crypto -Modul von node.js (zumindest zum Zeitpunkt des Schreibens) gilt nicht immer als stabil, sodass sich die API ändern kann. In der Tat werden die Methoden, die jeder im Internet zum Abrufen des Hashes (md5, sha1, ...) einer Datei verwendet, als Vermächtnis angesehen (aus der Dokumentation von Hash class ) (Anmerkung: Hervorhebung meines):

Klasse: Hash

Die Klasse zum Erstellen von Hash-Digests von Daten.

Es ist ein Stream, der sowohl lesbar als auch beschreibbar ist. Die geschriebenen Daten sind wird verwendet, um den Hash zu berechnen. Sobald die beschreibbare Seite des Streams .__ ist. Verwenden Sie die Methode read (), um den berechneten Hash-Digest abzurufen. Das veraltete Update- und Digest-Methoden werden ebenfalls unterstützt.

Wird von crypto.createHash zurückgegeben.

Obwohl hash.update und hash.digest als Erbe betrachtet werden, werden sie im Beispiel oberhalb des zitierten Snippets verwendet.

Was ist der richtige Weg, um Hashes zu erhalten, ohne diese alten Methoden zu verwenden?

34

Aus dem zitierten Ausschnitt in der Frage:

[die Hash-Klasse] Es ist ein Stream, der sowohl lesbar als auch beschreibbar ist. Die geschriebenen Daten sind wird verwendet, um den Hash zu berechnen. Sobald die beschreibbare Seite des Streams .__ ist. Verwenden Sie die Methode read (), um den berechneten Hash-Digest abzurufen.

Was Sie also brauchen, um etwas Text zu markieren ist:

var crypto = require('crypto');

// change to 'md5' if you want an MD5 hash
var hash = crypto.createHash('sha1');

// change to 'binary' if you want a binary hash.
hash.setEncoding('hex');

// the text that you want to hash
hash.write('hello world');

// very important! You cannot read from the stream until you have called end()
hash.end();

// and now you get the resulting hash
var sha1sum = hash.read();

Wenn Sie den Hash einer Datei abrufen möchten, erstellen Sie am besten einen ReadStream aus der Datei und leiten ihn in den Hash:

var fs = require('fs');
var crypto = require('crypto');

// the file you want to get the hash    
var fd = fs.createReadStream('/some/file/name.txt');
var hash = crypto.createHash('sha1');
hash.setEncoding('hex');

fd.on('end', function() {
    hash.end();
    console.log(hash.read()); // the desired sha1sum
});

// read all file and pipe it (write it) to the hash object
fd.pipe(hash);
70

Kurze Version von Carlos Antwort:

var fs = require('fs')
var crypto = require('crypto')

fs.createReadStream('/some/file/name.txt').
  pipe(crypto.createHash('sha1').setEncoding('hex')).
  on('finish', function () {
    console.log(this.read()) //the hash
  })
12

Eine ES6-Version, die ein Versprechen für den Hash-Digest zurückgibt:

function checksumFile(hashName, path) {
  return new Promise((resolve, reject) => {
    let hash = crypto.createHash(hashName);
    let stream = fs.createReadStream(path);
    stream.on('error', err => reject(err));
    stream.on('data', chunk => hash.update(chunk));
    stream.on('end', () => resolve(hash.digest('hex')));
  });
}
11
DS.

Weiter polnisch, ECMAScript 2015

function checksumFile(algorithm, path) {
  return new Promise((resolve, reject) =>
    fs.createReadStream(path)
      .on('error', reject)
      .pipe(crypto.createHash(algorithm)
        .setEncoding('hex'))
      .once('finish', function () {
        resolve(this.read())
      })
  )
}
7
Harald Rudell
var fs = require('fs');
var crypto = require('crypto');
var fd = fs.createReadStream('data.txt');
var hash = crypto.createHash('md5');
hash.setEncoding('hex');
fd.pipe(hash);
hash.on('data', function (data) {
    console.log('# ',data);
});
0
javelinthrow