node.js 使用加密模块的流功能获取文件的哈希值(即:没有 hash.update 和 hash.digest)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18658612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:32:25  来源:igfitidea点击:

Obtaining the hash of a file using the stream capabilities of crypto module (ie: without hash.update and hash.digest)

node.jshashstream

提问by Carlos Campderrós

The cryptomodule of node.js (at the time of this writing at least) is not still deemed stable and so the API may change. In fact, the methods that everyone in the internet use to get the hash (md5, sha1, ...) of a file are considered legacy (from the documentation of Hashclass) (note: emphasis mine):

cryptonode.js的模块(至少在撰写本文时)仍被视为不稳定,因此 API 可能会更改。事实上,互联网上每个人用来获取文件哈希(md5,sha1,...)的方法都被认为是遗留的(来自Hashclass的文档)(注意:强调我的):

Class: Hash

The class for creating hash digests of data.

It is a stream that is both readable and writable. The written data is used to compute the hash. Once the writable side of the stream is ended, use the read() method to get the computed hash digest. The legacy update and digest methodsare also supported.

Returned by crypto.createHash.

类别:哈希

用于创建数据哈希摘要的类。

它是一个既可读又可写的流。写入的数据用于计算散列。一旦流的可写端结束,使用 read() 方法获取计算的哈希摘要。在 传统的更新和摘要方法也支持。

由 crypto.createHash 返回。

Despite hash.updateand hash.digestbeing considered legacy, the example shown just above the quoted snippet is using them.

尽管hash.updatehash.digest正在考虑遗产,只是引用片段上面的例子中使用它们。

What's the correct way of obtaining hashes without using those legacy methods?

在不使用这些遗留方法的情况下获取哈希的正确方法是什么?

回答by Carlos Campderrós

From the quoted snippet in the question:

从问题中引用的片段:

[the Hash class] It is a stream that is both readable and writable. The written data is used to compute the hash. Once the writable side of the stream is ended, use the read() method to get the computed hash digest.

【Hash类】是一个可读可写的流。写入的数据用于计算散列。一旦流的可写端结束,使用 read() 方法获取计算的哈希摘要。

So what you need to hash some text is:

所以你需要散列一些文本是:

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

If you want to get the hash of a file, the best way is create a ReadStream from the file and pipe it into the hash:

如果要获取文件的哈希值,最好的方法是从文件创建一个 ReadStream 并将其通过管道传输到哈希值中:

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

回答by DS.

An ES6 version returning a Promise for the hash digest:

ES6 版本为哈希摘要返回一个 Promise:

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

回答by Afanasii Kurakin

Short version of Carlos' answer:

卡洛斯回答的简短版本:

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

回答by Harald Rudell

Further polish, ECMAScript 2015

进一步润色,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())
      })
  )
}

回答by javelinthrow

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

回答by Lacoste

I use Node module hasha successfully, the code becomes very clean and short. It returns a promise, so you can use it with await:

我成功地使用了 Node 模块 hasha,代码变得非常干净和简短。它返回一个 promise,因此您可以将它与 await 一起使用:

const hasha = require('hasha');

const fileHash = await hasha.fromFile(yourFilePath, {algorithm: 'md5'});