字符串哈希用sha256.Sum256([]byte(s)),零分配且快;文件哈希必须流式处理:os.Open→sha256.New()→io.Copy,禁用os.ReadFile以防OOM;注意Sum256返回[32]byte,Sum(nil)返回[]byte,类型不可混用。

直接用 sha256.Sum256([]byte(s)) 算字符串,用 os.Open + sha256.New() + io.Copy 算文件——其他写法要么错、要么慢、要么内存爆炸。
字符串哈希:优先用 sha256.Sum256
sha256.Sum256 是零分配、快、代码短的最优解,适合纯字符串或小数据(比如密码、token、配置项)。它返回的是 [32]byte 结构体,不是 []byte,这点必须记牢。
- 转十六进制字符串直接用
fmt.Sprintf("%x", sum),不用引入encoding/hex,轻量又快 - 要 Base64 编码时,必须写成
sum[:]转切片,再喂给base64.StdEncoding.EncodeToString - 别写
fmt.Println(sum)——输出是{[123 45 ]}这种结构体字面量,不是哈希串 - 别把
sum直接传给需要[]byte的函数(比如json.Marshal),会编译失败
文件哈希:必须流式处理,禁用 os.ReadFile
哪怕就 100MB 的文件,用 os.ReadFile 也会 OOM;Go 标准库没有 sha256.File(),你得自己搭流水线。三步固定套路不能省:
-
os.Open打开文件,记得defer file.Close(),否则跑几天后报too many open files -
sha256.New()创建哈希器 -
io.Copy(hasher, file)流式写入,内部自动分块(默认 32KB),不占额外内存 -
io.Copy返回值必须检查错误:磁盘满、权限不足、NFS 中断都会在这里暴露,忽略等于线上事故 - 机械硬盘上建议包一层
bufio.NewReader(file),SSD 可省
Sum256() 和 Sum(nil) 别混用
两者类型不兼容,语义完全不同,强行赋值或传参会编译失败:
-
sha256.Sum256(data)返回[32]byte值类型,可作 map key 或结构体字段,适合小数据一次性计算 -
sha256.New().Sum(nil)返回[]byte,是hash.Hash接口的标准收尾方式,适用于流式场景(如文件、网络流、多次Write) -
Sum(nil)中的nil表示不复用底层数组,安全但略慢;高频计算可预分配make([]byte, 0, sha256.Size)传入 - 别写
h.Sum([]byte("xxx"))——那是把哈希值追加到输入字节后面,不是“用输入算哈希”
输出哈希串时,fmt.Sprintf("%x", ...) 比 hex.EncodeToString 更干净
只要你的哈希器实现了 hash.Hash 接口(比如 sha256.New()),Sum(nil) 返回的 []byte 就能直接喂给 %x;sha256.Sum256 返回的 [32]byte 也支持 %x 自动转切片。
-
fmt.Sprintf("%x", h.Sum(nil))不依赖encoding/hex,代码更干净,性能略优(尤其短字符串) - 别写
hex.EncodeToString(h.Sum(nil)[:])——h.Sum(nil)已是[]byte,[:]是冗余操作 - 校验两个文件是否一致?分别算 SHA256 字符串再
==比较,比bytes.Equal整个文件快几个数量级 - MD5 已不该出现在新代码里,除非对接老旧协议;SHA256 是当前平衡安全性、性能与兼容性的默认选择
最易被忽略的其实是错误处理和类型转换:文件读取失败、哈希器类型误用、结构体与切片混用——这些坑在线上环境不会立刻报错,但会在某次大文件上传、并发压测或跨平台部署时突然爆发。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











