哈希与校验和:为什么 CRC32 和 MD5 得自己写

浏览器只在安全上下文提供 SHA 系列,CRC32 与 MD5 不在 Web Crypto 里。顺带解决大文件不该一次读进内存,以及校验值不该靠人眼比对。

为什么有两个算法要手写

crypto.subtle.digest 提供 SHA-1/256/384/512,快且不需要自己维护位运算。但它没有 CRC32,也没有 MD5——这两个恰恰是下载校验、压缩格式、分片标识里最常见的。

所以 CRC32 用查表法实现:预先算出 256 项表,逐字节异或查表,几十行就够。MD5 按 RFC 1321 实现,麻烦的地方在字节序:消息长度填充与输出都是小端,中间状态是大端,写反了结果对不上,而且不会有任何报错,只会得到一个看似合理的错误十六进制串。

文件不能一次读进内存

把整个文件当字符串读进来做哈希,对小文件没问题,对几百兆的安装包就是灾难。正确做法是分块读:拿到 ArrayBuffer 的切片后喂给同一个哈希实例,最后统一取出结果。

SHA 系列天然支持这个模式,手写的 CRC32 与 MD5 也要按「可增量更新」的形态来写,而不是写成一次性函数。这是设计实现时就该定下的形状。

粘贴期望值,让工具来比对

校验的实际场景是:你手上有官方公布的校验值,下载完想确认文件没被篡改。逐字符比对 64 位十六进制既枯燥又不可靠——大小写、空格、少一位都看不出来。

所以我把「期望值」做成一个输入框:贴进去,工具告诉你它是哪一种算法算出来的,或者一个都没对上。这一步把校验从视觉比对变成了明确结论。

一句必要的提醒

MD5 与 SHA-1 已经不适合做安全用途,碰撞成本低到不可接受。这个工具保留它们是为了完整性校验——确认传输没有出错——不是用于签名或口令。如果用途是抵御主动攻击,请用 SHA-256 及以上。

自检覆盖

手写密码学实现必须用已知向量验证,否则「能输出 32 位十六进制」和「结果正确」是两回事。自检脚本里用标准测试向量逐个核对,例如 “abc” 的 MD5 是 900150983cd24fb0d6963f7d28e17f72,这样重构时不会悄悄改坏。

← 返回文章列表

评论

…