用 sha256 校验 Windows 下载文件:从 EZA Modern LS 说起

用 sha256 校验 Windows 下载文件:从 EZA Modern LS 说起

我下载开源软件有个固定习惯:文件落到 Downloads 文件夹之后,先算一遍 SHA-256,再双击安装。这个习惯是被一次失败经历养成的------某个工具的下载页在 CDN 边缘节点上返回了半截文件,大小看着差不多,装到一半才报错。从那以后,哈希校验成了我流程里的第一步,而不是可选项。这篇就按我实际操作的顺序写,以 EZA Modern LS 这个 Windows 上的 ls 替代工具为例,把命令、失败场景和边界情况都过一遍。

先把文件放好,再谈校验

我一般会新建一个临时目录,避免和下载文件夹里的同名旧文件混淆:

powershell 复制代码
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\Downloads\verify" | Out-Null
Move-Item "$env:USERPROFILE\Downloads\eza-modern-ls*.zip" "$env:USERPROFILE\Downloads\verify\"
Get-ChildItem "$env:USERPROFILE\Downloads\verify\"

路径里带空格、带中文的情况我都遇到过,所以命令里一律用引号包住 $env:USERPROFILE 展开后的路径。文件名也确认一遍:如果下载页给的是 eza-modern-ls-v0.x.x-x86_64.zip,而你手里是浏览器自动加后缀的 eza-modern-ls (1).zip,那说明你之前下过一次,先删旧的再校验,否则很容易拿错文件去比对。

Windows 上的两种算法子:certutil 与 Get-FileHash

Windows 自带两条路。老系统、受限环境里我常用 certutil,它不需要 PowerShell:

cmd 复制代码
certutil -hashfile "%USERPROFILE%\Downloads\verify\eza-modern-ls.zip" SHA256

输出是三行:第一行是算法名,第二行是哈希,第三行是完成提示。注意 certutil 默认输出大写十六进制,中间没有分隔符。

PowerShell 里我更倾向 Get-FileHash,因为它返回对象,方便脚本里继续处理:

powershell 复制代码
$file = "$env:USERPROFILE\Downloads\verify\eza-modern-ls.zip"
$actual = (Get-FileHash -Path $file -Algorithm SHA256).Hash.ToLower()
$expected = "把下载页公布的哈希粘贴到这里".ToLower()
if ($actual -eq $expected) {
    "OK  $actual"
} else {
    "MISMATCH"
    "expected: $expected"
    "actual  : $actual"
}

两个细节值得说。第一,大小写:不同来源公布的哈希可能大小写混用,比较前统一转小写,省得肉眼比对时误判。第二,Get-FileHash 在 PowerShell 5.1 和 7.x 上都可用,但如果你的文件在 UNC 路径(\\server\share\...)上,先复制到本地再算,网络中断会让哈希计算直接抛异常。

校验失败时我按这个顺序排查

哈希对不上,先别急着怀疑被篡改。我遇到的绝大多数情况是下面几类:

文件没下完。 浏览器显示"已完成"不代表字节完整,尤其是断点续传之后。对比文件大小和下载页标注的大小,差几个 KB 就是没下完,重新下载即可 revoke 掉旧文件。

下错了版本。 同一个项目常有 x86_64、aarch64、portable、setup 多个包,哈希各不相同。看文件名里的架构标识,别拿 ARM 包的哈希去校验 x64 包。

多了一层解压。 有些站点公布的是压缩包内可执行文件的哈希,不是 zip 本身的哈希。这种情况要么先解压再对 .exeutu 算,要么去页面确认哈希对应的是哪一层。我在 EZA Modern LS 这类工具上就吃过这个亏,页面写的是归档文件哈希,我却解压后去算里面的 eza.exe。

复制粘贴带了空格或换行。 从网页复制哈希时,行尾常混入不可见字符。用 $expected.Trim() 清一下,或者干脆把哈希写进一个 .sha256 文件再读。

如果以上都排除,文件大小一致、来源可信、哈希仍然不符,那就不要运行它,删掉,换官方镜像或等一段时间重下。这不是过度谨慎,而是校验存在的意义。

边界情况:大文件、批量与自校验文件

单个几十 MB 的 zip,Get-FileHash 一两秒就完事。但如果是几个 GB 的镜像,计算期间会占满一个核,机械硬盘上还可能拖慢其他 IO。我的做法是放到后台任务里跑,前台继续干别的:

powershell 复制代码
$job = Start-Job -ScriptBlock {
    param($p)
    (Get-FileHash -Path $p -Algorithm SHA256).Hash
} -ArgumentList "$env:USERPROFILE\Downloads\verify\eza-modern-ls.zip"
Wait-Job $job | Out-Null
Receive-Job $job
Remove-Job $job

批量校验时,很多项目会附带一个 SHA256SUMS 文件,格式是"哈希 + 两个空格 + 文件名"。PowerShell 没有内置的 sha256sum -c,我写了个小循环读它:

powershell 复制代码
$dir = "$env:USERPROFILE\Downloads\verify"
Get-Content "$dir\SHA256SUMS" | ForEach-Object {
    if ($_ -match '^([0-9a-fA-F]{64})\s+\*?(.+)$') {
        $expected = $Matches[1].ToLower()
        $name = $Matches[2].Trim()
        $actual = (Get-FileHash -Path (Join-Path $dir $name) -Algorithm SHA256).Hash.ToLower()
        "{0}  {1}" -f ($(if ($actual -eq $expected) { "OK" } else { "FAIL" })), $name
    }
}

这里有个坑:SHA256SUMS 里的文件名可能带 ./ 前缀或子目录,Join-Path 拼出来会找不到文件。遇到报错就先把文件列表打印出来,确认路径形态再改正则。

还有一种情况是工具自身提供校验子命令,比如某些安装器支持 --verify,但那属于工具行为,不能替代对下载文件本身的哈希计算------文件在运行前就已经可能被替换了。

相关资源

EZA Modern LS 的下载页和校验信息可以在 GitVaults 上找到,我一般直接从那里取公布的 SHA-256 值来比对:EZA Modern LS。下载后按上面的流程走一遍,再解压使用,整个过程不到一分钟,但能挡掉不少低级问题。

一点说明

以上命令都在 Windows 11 + PowerShell 7.4 和 Windows 10 + PowerShell 5.1 上实际跑过,certutil 部分在 cmd 里验证。如果你在 WSL 或 Git Bash 里习惯用 sha256sum,思路一样,只是比较逻辑换成 sha256sum -c。你在校验下载文件时遇到过哪些奇怪情况------比如哈希页和实际文件对不上、或者压缩包内文件哈希与归档哈希混用------欢迎补充,我会把常见场景整理进后续的实操笔记。

相关推荐
miofly2 小时前
Gemini 4 Argon发布,机器人ERQA推理得分87%但缺可比基准
开源·github
Apageoflove2 小时前
把 ComfyUI 改造成无人值守视频产线:状态机、顺序锁与 ComfyUI 插件工程实践
人工智能·github
CoovallyAIHub4 小时前
Anthropic 昨晚发布 Claude Duet:AI 第一次主动找你干活
github·agent·设计
逛逛GitHub4 小时前
又盘点了 4 个稀奇古怪的 GitHub 项目,第一个很抽象。
github
m4Rk_7 小时前
【论文阅读】Agent记忆机制(106):COUNTERMEM——用可执行世界模型验证“如果当时换个动作”的反事实记忆
论文阅读·人工智能·学习·开源·github
十方空烬7 小时前
开源雷达 · 2026-10-21:技能开始像软件包一样被治理
开源·github
夏天要喝冰可乐7 小时前
我用 WorkBuddy 做了个「GitHub 考古所」:输入一个用户名,出土你的编程人格档案
前端·github
miofly8 小时前
GitHub 今日推荐|Snapintosh:用 ARM EL2 监控器骗过内核,让骁龙芯片笔记本跑 macOS
python·开源·github