You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中ReadableStream.pipe计算Crypto Hash结果错误问题

为什么Node.js中用pipe计算SHA256哈希得到错误结果?

我尝试用两种方法计算SHA256哈希值,但只有其中一种方法得到了正确结果。测试代码如下:

import { createHash } from 'node:crypto';
import { Readable } from 'node:stream';

function f1(info: NodeJS.ReadableStream) {
  return new Promise((resolve, reject) => {
    const hash = createHash('sha256');

    info.on('data', (data) => hash.update(data));
    info.on('end', () => resolve(hash.digest('hex')));
    info.on('error', (error) => reject(error));
  });
}

function f2(info: NodeJS.ReadableStream){
  const hasher = createHash('sha256');
  return info.pipe(hasher).digest('hex');
}

export async function test() {
  const h1 = await f1(Readable.from('Testing'));
  const h2 = f2(Readable.from('Testing'));

  console.log(h1);
  console.log(h2);
}

test();

运行输出:

e806a291cfc3e61f83b98d344ee57e3e8933cccece4fb45e1481f1f560e70eb1
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

仅方法f1返回了正确的哈希值,请问这是什么原因?


问题原因

f2的问题在于Stream的pipe操作是异步的,你直接调用digest('hex')的时候,可读流的数据还没来得及写入哈希器,此时哈希器处理的是空输入,所以得到的是空字符串的SHA256哈希值(e3b0c442...)。

而f1通过监听data和end事件,确保在所有数据都写入哈希器后才调用digest,所以能得到正确结果。

修正后的f2实现

要让f2正确工作,需要等到流的finish事件触发后再调用digest,可以把它包装成Promise:

function f2(info: NodeJS.ReadableStream) {
  return new Promise((resolve, reject) => {
    const hasher = createHash('sha256');
    info.pipe(hasher);
    
    hasher.on('finish', () => {
      resolve(hasher.digest('hex'));
    });
    
    info.on('error', reject);
  });
}

同时在test函数里需要用await调用f2,确保异步操作完成后再获取结果:

export async function test() {
  const h1 = await f1(Readable.from('Testing'));
  const h2 = await f2(Readable.from('Testing'));

  console.log(h1);
  console.log(h2);
}

修改后,f2就能输出和f1一致的正确哈希值。

内容的提问来源于stack exchange,提问作者Henry M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:02:42