web-dev-qa-db-fra.com

Obtenir le hachage d'un fichier en utilisant les capacités de flux du module de cryptage (c'est-à-dire sans hash.update et hash.digest)

Le module crypto de node.js (au moins au moment de l'écriture) n'est pas encore considéré comme stable et l'API peut donc changer. En fait, les méthodes utilisées par tout le monde sur Internet pour obtenir le hachage (md5, sha1, ...) d’un fichier sont considérées comme héritées (de la documentation de Hash class ) (note: c’est le mot emphase):

Classe: Hash

Classe de création de condensés de hachage de données.

C'est un flux qui est à la fois lisible et accessible en écriture. Les données écrites sont utilisé pour calculer le hachage. Une fois que le côté inscriptible du flux est terminé, utilisez la méthode read () pour obtenir le condensé de hachage calculé. Le Les méthodes legacy update et digest sont également prises en charge.

Renvoyé par crypto.createHash.

Bien que hash.update et hash.digest soient considérés comme hérités, l'exemple présenté juste au-dessus de l'extrait cité les utilise.

Quelle est la bonne façon d'obtenir des hachages sans utiliser ces méthodes héritées?

34
Carlos Campderrós

Extrait de l'extrait cité dans la question:

[la classe Hash] C'est un flux qui est à la fois lisible et accessible en écriture. Les données écrites sont utilisé pour calculer le hachage. Une fois que le côté inscriptible du flux est terminé, utilisez la méthode read () pour obtenir le condensé de hachage calculé.

Donc, ce dont vous avez besoin pour hacher du texte, c'est:

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

Si vous voulez obtenir le hachage d'un fichier, le meilleur moyen est de créer un ReadStream à partir du fichier et de le rediriger vers le hachage:

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
Carlos Campderrós

Version courte de la réponse de Carlos:

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
Afanasii Kurakin

Une version ES6 renvoyant une promesse pour le condensé de hachage:

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.

Autre finition, 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