"我在 Mac 上算出来的 MD5 和 Linux 上不一样"——这类问题你大概率也碰到过。同一个文件,同一个 hash 工具,不同机器上结果不一样,原因往往不是工具 bug,而是文件在传递过程中被"悄悄"修改了。

这篇文章把 hash 计算的 5 个高频坑讲透:文件换行符、文本编码、BOM、二进制 vs 文本模式、大小写敏感。配合在线 hash 工具快速定位。

坑 1:换行符 CRLF vs LF

Windows 下文本文件用 \r\n(CRLF),Linux/macOS 用 \n(LF)。同一个文件在不同操作系统上打开、保存、复制,换行符就可能被悄悄替换。hash 算的是原始字节,换行符一变 hash 必然变。

# Linux:把 Windows 换行符转成 LF 再算 hash
dos2unix file.txt
md5sum file.txt

# 或直接用 git checkout -- eol=lf

判断方法:把文件拖进 在线 hash 工具 算一次文件 hash,再把文件内容粘进文本框算一次文本 hash。两次结果不一致,说明文件里存在肉眼看不见的字节差异(换行符、BOM、编码都算)。

坑 2:文本编码 UTF-8 vs GBK

同样的中文字符串,UTF-8 编码每个汉字占 3 字节、GBK 占 2 字节、UTF-16 占 2 字节。内容看起来没变,编码变了 hash 就一定不同。

# 强制 UTF-8 编码后再算
iconv -f GBK -t UTF-8 file.txt | md5sum

坑 3:BOM(Byte Order Mark)

某些编辑器(VS Code、Windows 记事本)保存 UTF-8 文件时会自动加 BOM(3 字节 EF BB BF)。两个"看起来一样"的文件,一个有 BOM 一个没有,hash 一定不同。

# Linux(GNU sed 支持十六进制转义)
sed -i '1s/^\xEF\xBB\xBF//' file.txt

# macOS 的 BSD sed 不认 \x 转义,改用 perl
perl -i -pe 's/^\xEF\xBB\xBF//' file.txt

# 或用 file 命令看有没有 BOM
file file.txt   # UTF-8 Unicode text, with BOM

在线 hash 工具 按原始字节计算,BOM 不会被跳过——所以带 BOM 和不带 BOM 的同一段文本,算出来结果必然不同,正好印证这个坑。想确认 BOM,比看 hash 更直接的办法是比文件字节数:同一段文字,带 BOM 的版本正好多 3 字节。

坑 4:不同 hash 算法长度不同

算法 输出长度(十六进制字符数) 碰撞风险 适用场景
MD5 32 ⚠️ 已证明有碰撞 文件完整性校验(非安全场景)
SHA-1 40 ⚠️ 已证明有碰撞 Git commit / 证书指纹
SHA-256 64 ✅ 当前安全 文件校验、HMAC 签名
SHA-512 128 ✅ 当前安全 安全要求高的场景

MD5 不是"没用"了——用于文件完整性校验完全够用(不是用于安全,是用于"文件没损坏/没被误改")。真正需要安全时用 SHA-256。

坑 5:大小写敏感

Windows 的 certutil 输出大写十六进制,Linux 的 md5sum / sha256sum 输出小写——同一个文件在两个平台的首字母大小写不同,值其实完全一致,比对前先统一大小写。如果你想让"Hello"和"hello"算出同一个 hash,那属于应用层归一化,得在算之前自己转小写,hash 函数本身不做这件事。

常见 hash 命令对比

# Linux
md5sum file.txt
sha256sum file.txt

# macOS(md5 命令自带,sha 开头)
md5 file.txt
shasum -a 256 file.txt

# Windows PowerShell(Get-FileHash)
Get-FileHash file.txt -Algorithm MD5
Get-FileHash file.txt -Algorithm SHA256

注意:macOS 的 md5 和 Linux 的 md5sum 参数格式不一样;Windows 的 Get-FileHash 输出格式和 Unix 工具也不一样。跨平台验证 hash 时,用 在线 hash 工具 作为基准最稳妥——浏览器环境天然一致,不受系统影响。

用在线 hash 工具定位差异

在线 hash 工具 两个核心定位能力:

  1. 字符串 hash vs 文件 hash 双模式:输入文本按 UTF-8 编码算,或直接拖入文件按原始字节算(上限 5MB)——如果字符串 hash 对、文件 hash 不对,问题在文件字节
  2. 算法批量对比:一键输出 MD5 / SHA-1 / SHA-256 / SHA-512 四种结果,和本地工具对比哪一个匹配

常见坑

  • "文件没改但 hash 变了":Windows Defender / 杀毒软件可能悄悄加 NTFS Alternate Data Stream。用 dir /r 看有没有 :Zone.Identifier,或 Get-Item -Stream *。
  • "Git clone 下来 hash 就不一样":Git 有 core.autocrlf 配置,clone 时自动转换行符。用 git config --global core.autocrlf false 关掉。
  • "压缩包解开 hash 不一样":ZIP 里存的是原始字节(包括换行符),解开后又被 OS 转了一次换行符——解包时用 unzip -a 或 git checkout -- eol=lf。

相关工具

  • 在线 Hash 计算:MD5 / SHA-1 / SHA-256 / SHA-512,文本与文件双模式,文件按原始字节计算
  • HTTP 状态码速查:文件下载校验 hash 时 HTTP 头 ETag 就是文件 hash 变体