小字符串用md5.Sum(),大文件或流式数据必须用md5.New()配合io.Copy();前者返回[16]byte,后者需调用Sum(nil)获取结果;打印需hex.EncodeToString()或fmt.Sprintf("%x", hash),不可用string();安全场景应换sha256。

md5.Sum() 和 md5.New() 到底该用哪个?
小字符串直接用 md5.Sum(),干净利落;大文件或流式数据必须用 md5.New() 配合 io.Copy()。前者是“一次性快算”,后者是“边读边哈希”。混用会导致结果错乱或 panic。
-
md5.Sum([]byte(s))返回[16]byte固定数组,适合短文本(比如配置项、URL、键名) -
md5.New()返回hash.Hash接口,支持多次Write(),必须调用Sum(nil)获取最终结果 - 误写成
md5.New().Sum([]byte("x"))会把原始数据拼进 hash 结果里,不是你想要的 MD5
为什么 fmt.Println(md5.Sum(...)) 打印出来像乱码?
因为 md5.Sum() 返回的是结构体,不是字符串。直接打印看到的是字节序列(比如 {[187 242 109 ...]}),不是 32 位十六进制哈希串。
- 正确转换路径:先用
hash[:]转成切片,再用hex.EncodeToString() - 也可以用
fmt.Sprintf("%x", hash),但注意它只对md5.Sum类型有效,对hash.Sum(nil)返回的[]byte要写成fmt.Sprintf("%x", hash.Sum(nil)) - 别用
string(hash[:])——那是不可读的二进制,不是 hex
计算文件 MD5 时容易触发 OOM 或卡死?
用 os.ReadFile() 读整个文件再喂给 md5.Sum(),遇到几百 MB 的日志或 ZIP 就可能爆内存。Go 不会自动分块,得你手动流式处理。
- 必须打开文件句柄:
file, _ := os.Open("big.zip"),然后defer file.Close() - 用
io.Copy(hasher, file),底层自动按 32KB 左右分块读取,不占额外内存 - 机械硬盘上建议包一层
bufio.NewReader(file),提升小块读取效率 - 忽略
io.Copy的 error 是常见隐患:磁盘满、权限不足、文件被删都会在这里返回 err,不检查就等于默认成功
MD5 还能用吗?什么时候该换 sha256?
能用,但仅限非安全场景:缓存 key、临时去重、内部日志比对。只要涉及校验、签名、密码存储,立刻换成 crypto/sha256。
立即学习“go语言免费学习笔记(深入)”;
- MD5 碰撞已公开可构造,SHA256 目前仍是 NIST 推荐标准
- 接口几乎一致:
sha256.Sum()返回[32]byte,sha256.New()行为同 md5 - 性能差异不大,现代 CPU 上 SHA256 比 MD5 只慢约 10%~20%,但安全性天差地别
- 如果协议强制要求 MD5(比如某些老旧 CDN 的 ETag),那就用;否则默认选
sha256
最常被跳过的细节是 error 处理和 Sum(nil) 后的切片转换——这两步看着琐碎,但漏掉任何一个,哈希值就不可靠,而且问题很难复现。


















