md5.Sum()用于一次性小数据哈希,需用fmt.Sprintf("%x", sum)或hex.EncodeToString(sum[:])转字符串;md5.New()必须配io.Copy()处理流式数据,混用或误传参数会导致错误结果。
Go 里算 MD5 不是“会不会”的问题,而是“用错函数就得到错误结果”的问题。核心判断只有一条:
和
语义完全不同,不能混用,也不能靠直觉猜参数含义。
md5.Sum() 怎么用才不出错?
是一次性快算函数,输入完整
,返回结构体,内部是固定大小的
数组。它不维护状态、不支持追加写入,也不接受字符串直接传参。
正确写法:
,然后用
或
转成 32 位十六进制字符串
别写
:结果含不可见字节,可能 panic,且根本不是 hex 格式
别在循环里反复调用
并期望复用——它每次都是全新结构体,无状态可复用
打印
看到
不是 bug,是结构体默认输出;你要的是哈希值,不是结构体本身
md5.New() 必须配 io.Copy() 吗?
是的。因为
返回的是
接口,设计目标就是流式写入,内部有状态管理、缓冲区和填充逻辑。手动模拟读写极易出错。
标准写法:
—— 它自动处理短读、边界、缓冲(默认 32KB),且对
有底层优化路径
错误写法:自己开
,循环
再
—— 最后一次
的剩余字节会漏掉,MD5 值必然错误
别写
:参数是拼接缓冲区,不是待哈希数据;
的字节会被追加到最终结果里,导致哈希值多出内容
若真要控制缓冲区(极少数场景),用
,但 buf 长度只影响内存占用,不影响结果
计算文件 MD5 时最容易忽略的系统级错误
MD5 逻辑本身不会报错,但
和
阶段失败非常常见,且错误类型五花八门,必须显式检查
。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
立即学习
“
go语言免费学习笔记(深入)
”;
:权限不足,不是哈希问题,是系统调用失败
:传入了目录路径,
直接失败
符号链接默认被跟随;若只想算链接文件本身(而非目标内容),需先
判断类型,再决定是否
空文件能正常算:
对应
,无需特殊判断
别用
加载大文件——几百 MB 就可能 OOM,违背流式设计初衷
什么时候该换 SHA256?
MD5 在 Go 标准库中仍可用,但适用边界极其清晰:仅限非安全场景的完整性校验。只要涉及校验、签名、协议交互或任何存在对抗意图的场景,立刻换
。
安全场景必须换:密码存储、token 签名、API 请求验签、用户上传文件校验等
SHA256 接口几乎一致:
返回
,
行为同
,迁移成本极低
性能差异不大:现代 CPU 上 SHA256 比 MD5 只慢约 10%~20%,但安全性天差地别
协议强制要求 MD5(如某些老旧 CDN 的 ETag)除外;否则默认选
最常被跳过的细节是 error 处理和
后的切片转换——这两步看着琐碎,但漏掉任何一个,哈希值就不可靠,而且问题很难复现。
md5.Sum()md5.New()md5.Sum()[]byte[16]bytesum := md5.Sum([]byte("hello"))fmt.Sprintf("%x", sum)hex.EncodeToString(sum[:])string(sum[:])md5.Sum()sum{[138 214 110 ...]}md5.New()hash.Hashio.Copy(hasher, file)hash.Hashbuf := make([]byte, 4096)file.Read(buf)hasher.Write(buf)n < len(buf)md5.New().Sum([]byte("x"))"x"io.CopyBuffer(dst, src, buf)os.Openio.Copyerrpermission deniedread xxx: is a directoryos.Openos.Lstatos.Openmd5.Sum([]byte(""))d41d8cd98f00b204e9800998ecf8427eos.ReadFile()crypto/sha256sha256.Sum()[32]bytesha256.New()md5sha256Sum(nil)