md5.sum() 返回结构体而非字符串,需用 fmt.sprintf("%x", sum) 或 hex.encodetostring(sum[:]) 转换;go 1.22+ 已弃用该函数,长内容应优先使用 md5.new() 流式计算;md5 仅适用于校验等非安全场景,严禁用于密码存储。

md5.Sum() 返回的是结构体,不是字符串;直接打印会看到 {[138 214 110 ...]} 这类输出,而不是你想要的 32 位十六进制字符串。必须显式转换。
为什么 md5.Sum([]byte("x")) 打印出来像乱码
因为 md5.Sum() 返回类型是 md5.Sum(底层为 [16]byte),Go 默认用结构体格式打印。这不是错误,只是没转成可读形式。
- 错误写法:
fmt.Println(md5.Sum([]byte("hello")))→ 输出{[97 221 ...]} - 正确做法:用
fmt.Sprintf("%x", sum)或hex.EncodeToString(sum[:]) - 别写
string(sum[:])—— 会得到不可见字符甚至 panic -
sum[:]是必须的切片操作,sum本身不能当[]byte直接传给hex.EncodeToString
md5.Sum() 和 md5.New() 怎么选
两者适用场景不同,不是“哪个更好”,而是“哪个更合适”。
- 对短字符串(如缓存 key、参数拼接)用
md5.Sum():简洁、零分配、无状态 - 对长内容(文件、HTTP body、分段输入)必须用
md5.New()+Write()+Sum(nil):支持流式计算,内存可控 - Go 1.22+ 已将
md5.Sum()标记为 deprecated,官方倾向统一用流式路径 -
md5.Sum()不支持多次Write(),也不能复用;需要增量更新请用md5.New()配合Reset()
字符串编码不一致会导致哈希值不同
MD5 对字节敏感,同一逻辑字符串在不同编码或换行符下会产生完全不同结果。
- 确保始终用 UTF-8 编码:Go 字符串字面量默认是 UTF-8,但若从文件/网络读入,需确认
[]byte内容准确 - 注意换行符:
"a\nb"和"a\r\nb"的 MD5 完全不同 - 空格和 BOM:开头/结尾空格、UTF-8 BOM(
\ufeff)都会改变哈希 - 不要依赖
fmt.Sprintf拼接后再哈希——浮点数精度、map 遍历顺序等都可能引入非确定性
MD5 不是加密,也不能用于密码存储
这是最容易被忽略的实质问题:MD5 是单向哈希,不是加密;且它已被证实不安全。
- 别用
md5(salt + password)存密码——这不属于合规实践,也无法防彩虹表 - 校验场景可用:
文件下载后比对 md5sum、模板渲染缓存 key、内部服务间轻量指纹 - 涉及用户凭证、token 签名、数字签名等,必须换
bcrypt、scrypt或Argon2 - 标准库没提供加盐 MD5,也别自己拼接——哈希函数本身不解决盐管理、迭代、密钥派生等问题
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











