sha1.sum 返回固定长度结构体,适合短字符串栈上计算;sha1.new 返回 hash.hash 接口,支持流式写入。前者性能优、无 gc 开销,后者适用于大文件或网络数据分块处理。

直接用 crypto/sha1 计算字符串哈希值是可行的,但“独一无二”这个说法有陷阱——SHA-1 本身不保证全局唯一,只提供强抗碰撞性;实际项目中更推荐用 SHA-256 或更高强度算法,除非你明确受限于协议兼容性。
sha1.Sum 和 sha1.New 的区别在哪?什么时候该用哪个?
sha1.Sum 是一个固定长度(20 字节)的结构体,适合做栈上计算、避免内存分配;sha1.New() 返回一个实现了 hash.Hash 接口的对象,支持流式写入(比如处理大文件或网络数据)。如果你只是算一两个短字符串,优先用 sha1.Sum,性能略好且无 GC 开销。
- 用
sha1.Sum:先声明变量,再调用sum.Sum(nil)获取字节切片 - 用
sha1.New():必须显式调用h.Write([]byte(s)),再用h.Sum(nil) - 注意:
sum.Sum(nil)和h.Sum(nil)都会追加结果到参数切片末尾,传nil表示新建切片
为什么字符串转 []byte 后哈希结果和预期不符?
常见原因是忽略了 Go 字符串默认是 UTF-8 编码,而某些场景(比如对接旧系统)要求按原始字节解释。如果字符串含非 ASCII 字符(如中文、emoji),直接 []byte(s) 没问题;但如果原始输入其实是 GBK/UTF-16 编码的字节流,就必须先解码再哈希,否则结果不可复现。
- 纯 ASCII 字符串:直接
[]byte(s)安全 - 含中文等 Unicode 字符:仍可用
[]byte(s),因为 Go 字符串底层就是 UTF-8 字节序列 - 对接外部二进制协议时:确认输入编码,必要时用
golang.org/x/text/encoding转换 - 别用
string([]byte)反向转换来“验证”,这可能引入非法 UTF-8 序列
如何安全地把 SHA-1 结果转成十六进制字符串?
别手写循环拼接,用标准库 fmt.Sprintf("%x", sum) 或 hex.EncodeToString(sum[:])。前者简洁,后者可控性更强(比如可选大小写、是否加前缀)。注意:SHA-1 输出是 20 字节,转 hex 后固定为 40 个字符。
-
fmt.Sprintf("%x", sum)对sha1.Sum类型直接生效,对hash.Hash.Sum(nil)返回的[]byte也适用 -
hex.EncodeToString(sum[:])更明确,且能配合bytes.Equal做二进制比对 - 避免用
strconv.FormatUint等整数转换方式——SHA-1 不是单个整数,而是 20 字节序列
SHA-1 已被证明存在理论碰撞,NIST 早在 2011 年就建议停用。如果你在做签名、鉴权或长期存储校验,别只改个包名就上线,得同步评估业务是否接受潜在风险。真正需要“独一无二”的场景,优先考虑 crypto/sha256 或 crypto/sha512。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











