常见的情形是:下载页在安装包旁边写了一个 SHA-256,你想在运行之前核对一下,但不想为此打开命令行。本文说明这个核对能证明什么、浏览器怎样在不上传文件的情况下算出哈希,以及值对不上时该怎么做。

立即校验文件 →

为什么需要校验和

密码学哈希把任意字节流变成一段固定长度的「指纹」。下载校验用到它的两个性质:

  • 确定性:同样的字节总是得到同样的哈希。
  • 雪崩效应:输入里任何一位变化,整个输出都会变。

所以下载中断、镜像上的文件损坏、被代理改动过,SHA-256 都会不同。把发布方给的值和本机算出的值对一下,不用重新下载就能发现这些问题。

它本身不能证明文件的来源,那需要对校验列表的签名。但「我拿到的文件和发布方列出的是同一个」是其他一切的前提。

SHA-256 与旧算法

ZeroTool 的文件哈希校验工具支持六种算法,它们不能互相替代:

算法输出抗碰撞常见场合
CRC3232 位无,仅查错SFV 文件、ZIP 每个条目的 CRC-32 字段(APPNOTE)
MD5128 位已攻破(2004)较老的下载页
SHA-1160 位已攻破(2017,SHAttered)较老的下载页、Git 对象 ID
SHA-256256 位强Node.js 的 SHASUMS256.txt、Ubuntu 的 SHA256SUMS
SHA-384384 位强W3C SRI 规范里的示例
SHA-512512 位强Firefox 的 SHA512SUMS、npm 的 integrity 值

MD5 和 SHA-1「已攻破」是指攻击者能构造出两个哈希相同的不同文件。MD5 一致仍能说明下载没有意外损坏,但不能再说明没人故意改过,所以工具把 MD5、SHA-1 标为「旧」。

定规范时选 SHA-256。厂商只给 MD5 时照样核对,把结果当作传输检查,同时请厂商补上 SHA-256。

浏览器怎样计算哈希

浏览器自带的 crypto.subtle.digest() 只能一次性接收整块数据,不能分段输入。工具旧版正是这样做的,先用 File.arrayBuffer() 把整个文件读进内存:1 GB 文件让页面多占约 2 GB 内存,3 GB 文件直接失败。

现在改为流式计算。每种勾选的算法各用一个 Web Worker,用 file.stream() 按 1 MB 分块读取,交给 hash-wasm 逐块累加。每个线程只占约一块的内存。2026 年 10 月 1 日在 Apple M1 Max 的桌面 Chromium 上,1 GB 文件算 SHA-256 用 4.3 秒,页面多占约 100 MB 内存;4,080,486,400 字节的 Ubuntu 24.04.5 服务器版 ISO 与官方值一致。

文件不上传、不保存,唯一的网络请求是加载计算脚本本身。同样的流式写法:

import { createSHA256 } from 'hash-wasm';

async function sha256(file) {
  const hasher = await createSHA256();
  hasher.init();
  const reader = file.stream().getReader();
  for (;;) {
    const { done, value } = await reader.read();
    if (done) break;
    hasher.update(value);
  }
  return hasher.digest('hex');
}

对 new Blob(['abc']) 它返回 FIPS 180-2 的测试值 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad。

命令行里得到同样结果的写法:

# Linux(GNU coreutils)
sha256sum node-v24.21.0-win-x64.zip

# macOS
shasum -a 256 node-v24.21.0-win-x64.zip

# Windows
certutil -hashfile node-v24.21.0-win-x64.zip SHA256
Get-FileHash node-v24.21.0-win-x64.zip

输出格式各不相同:sha256sum 与 shasum 输出哈希加文件名,certutil 输出一行说明、一行哈希、一行完成提示,Get-FileHash 输出大写十六进制的表格。工具的核对框能读这些格式,也能读整份 SHA256SUMS、SHA256 (文件) = … 形式的标签行以及 Base64 / SRI 值,并按完整值比较。

实例:核对从 npmmirror 下载的 Node.js

Node.js 在每个版本目录里放一份 SHASUMS256.txt。2026 年 10 月 1 日核对,npmmirror 上 v24.21.0 的这份文件与 nodejs.org 的原文件逐字节相同,共 34 行,第 22 行是:

158f7685b44de51f6c0df1d153526cbcd3e1bc739a8dfc607721cef75de9e541  node-v24.21.0-win-x64.zip

下载这个 zip(37,618,919 字节),拖进文件哈希校验工具,把 34 行整份粘贴到核对框。SHA-256 会自动开始,卡片显示「与列表中 node-v24.21.0-win-x64.zip 的 SHA-256 一致(第 22 行)。」其余 33 行算作没有选择的文件,和 sha256sum -c --ignore-missing 的处理一样。

如果下载中断、只拿到前 30,000,000 字节,卡片会变红:「与列表中 node-v24.21.0-win-x64.zip 的 SHA-256 不一致(第 22 行),从第 1 个字符开始不同。」这时:

  1. 确认复制了完整的 64 位值、复制的是对应的那一行。少一个或多一个字符时,工具报的是长度或字符错误,不会当成不一致。
  2. 重新下载,最好换一个镜像;传输损坏是最常见的原因。
  3. 项目给校验列表签了名的,先验证签名再相信列表里的值。Node.js 在 Verifying binaries 里说明了 SHASUMS256.txt.asc 的用法,Ubuntu 提供 SHA256SUMS.gpg 和验证教程。列表被篡改时,哈希一致也说明不了什么。

工具只做到算哈希为止。验证签名需要发布方的 OpenPGP 公钥,应该在自己电脑上用 gpg --verify 完成。

工具不会替你解决的情况

  • 超大文件需要时间。 没有固定上限,但耗时随大小增加,算完之前页面要一直开着。
  • 文件夹没有单一哈希。 拖入文件夹时,工具会逐个计算里面的文件(最多 1,000 个),保留相对路径,方便按文件名对应 SHA256SUMS。要给整个文件夹一个指纹,先打包成 .tar.gz 或 .zip 再算。
  • 边下载边计算。 工具读取的是已经在磁盘上的文件。边下边算是命令行的做法(curl … | sha256sum)。
  • 其他算法和问题。 SHA-224、SHA3、BLAKE2、BLAKE3 不计算,会提示不支持。带密钥的完整性校验用 HMAC 生成器,存储密码用 Bcrypt 加密与校验,算文字而不是文件的哈希用哈希生成器。

独立工具在哪些场合更方便

熟悉命令行的开发者会直接用 sha256sum。但很多下载发生在别的场合:Windows 电脑、受管控的办公机、帮同事排查问题。浏览器工具适合这些情况:

  • macOS、Windows、Linux、ChromeOS 上是同一个页面。
  • 不用安装,也不需要管理员权限。
  • 直接处理磁盘上已有的文件,支持拖入文件和文件夹。
  • 粘贴一个值或整份校验列表就能按文件名核对,不用肉眼比 64 个字符。

它不是签名验证工具,也替代不了 CI 里的完整性检查。

延伸阅读