// Package sha256x 提供 SHA-224 与 SHA-256 摘要计算,以及十六进制/Base64 编码与流式、文件接口。 // // 命名约定:带位数后缀的函数(Sum224、Hex224、New224 等)明确指定算法变体; // 不带后缀的 Sum、Hex、Base64、New、SumReader、HexReader、HexFile 等价于 256 位变体, // 因为 SHA-256 是本包最常用的变体。 package sha256x import ( "crypto/sha256" "encoding/base64" "encoding/hex" "fmt" "hash" "io" "os" ) const ( // Size224 是 SHA-224 摘要的字节数(28)。 Size224 = sha256.Size224 // Size256 是 SHA-256 摘要的字节数(32)。 Size256 = sha256.Size // BlockSize 是 SHA-224/SHA-256 分组的字节数(64)。 BlockSize = sha256.BlockSize ) // New224 返回一个计算 SHA-224 摘要的 hash.Hash。 func New224() hash.Hash { return sha256.New224() } // New256 返回一个计算 SHA-256 摘要的 hash.Hash。 func New256() hash.Hash { return sha256.New() } // New 等价于 New256。 func New() hash.Hash { return New256() } // Sum224 返回 data 的 SHA-224 摘要(Size224 字节原始数据)。 func Sum224(data []byte) []byte { return sum(sha256.New224(), data) } // Sum256 返回 data 的 SHA-256 摘要(Size256 字节原始数据)。 func Sum256(data []byte) []byte { return sum(sha256.New(), data) } // Sum 等价于 Sum256。 func Sum(data []byte) []byte { return Sum256(data) } // Hex224 返回 data 的 SHA-224 摘要的小写十六进制字符串。 func Hex224(data []byte) string { return hex.EncodeToString(Sum224(data)) } // Hex256 返回 data 的 SHA-256 摘要的小写十六进制字符串。 func Hex256(data []byte) string { return hex.EncodeToString(Sum256(data)) } // Hex 等价于 Hex256。 func Hex(data []byte) string { return Hex256(data) } // Base64Sum224 返回 data 的 SHA-224 摘要的标准 Base64 字符串。 func Base64Sum224(data []byte) string { return base64.StdEncoding.EncodeToString(Sum224(data)) } // Base64Sum256 返回 data 的 SHA-256 摘要的标准 Base64 字符串。 func Base64Sum256(data []byte) string { return base64.StdEncoding.EncodeToString(Sum256(data)) } // Base64 等价于 Base64Sum256。 func Base64(data []byte) string { return Base64Sum256(data) } // SumReader 读取 r 中的全部数据并返回其 SHA-256 摘要;读取失败时返回包装后的 error。 func SumReader(r io.Reader) ([]byte, error) { return sumReader(sha256.New(), r) } // HexReader 读取 r 中的全部数据并返回其 SHA-256 摘要的小写十六进制字符串。 func HexReader(r io.Reader) (string, error) { sum, err := SumReader(r) if err != nil { return "", err } return hex.EncodeToString(sum), nil } // HexFile 计算 path 所指向文件的 SHA-256 摘要并返回小写十六进制字符串; // 文件不存在或读取失败时返回包装后的 error,不 panic。 func HexFile(path string) (string, error) { return hexFile(path, sha256.New) } // sum 把 data 一次性写入 h 并取出摘要。 func sum(h hash.Hash, data []byte) []byte { _, _ = h.Write(data) return h.Sum(nil) } // sumReader 把 r 的全部内容写入 h 并取出摘要。 func sumReader(h hash.Hash, r io.Reader) ([]byte, error) { if r == nil { return nil, fmt.Errorf("sha256x: 读取器为 nil") } if _, err := io.Copy(h, r); err != nil { return nil, fmt.Errorf("sha256x: 读取数据失败: %w", err) } return h.Sum(nil), nil } // hexFile 计算文件的小写十六进制摘要,newHash 提供具体算法实例。 func hexFile(path string, newHash func() hash.Hash) (string, error) { f, err := os.Open(path) if err != nil { return "", fmt.Errorf("sha256x: 打开文件 %q 失败: %w", path, err) } defer f.Close() sum, err := sumReader(newHash(), f) if err != nil { return "", fmt.Errorf("sha256x: 计算文件 %q 摘要失败: %w", path, err) } return hex.EncodeToString(sum), nil }