完善不同加密方法的使用
This commit is contained in:
+347
-29
@@ -1,45 +1,363 @@
|
||||
// Package sha3x 提供 SHA3-224/256/384/512 摘要计算与 SHAKE128/SHAKE256 可扩展输出函数(XOF),
|
||||
// 并附带十六进制/Base64 编码与流式、文件接口。
|
||||
//
|
||||
// SHAKE 是 XOF:输出长度由调用方指定,必须显式校验。本包要求 outputLength 在
|
||||
// [1, MaxShakeOutputLength] 之间,超出范围返回 error 而不是 panic 或分配巨大内存。
|
||||
//
|
||||
// 命名约定:带位数后缀的函数(Sum224、Hex224、New224 等)明确指定算法变体;
|
||||
// 不带后缀的 Sum、Hex、Base64、New、SumReader、HexReader、HexFile 等价于 256 位变体。
|
||||
package sha3x
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
// SHA3-256 哈希
|
||||
func Sha3_256(src string) string {
|
||||
h := sha3.New256()
|
||||
h.Write([]byte(src))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
const (
|
||||
// Size224 是 SHA3-224 摘要的字节数(28)。
|
||||
Size224 = 28
|
||||
// Size256 是 SHA3-256 摘要的字节数(32)。
|
||||
Size256 = 32
|
||||
// Size384 是 SHA3-384 摘要的字节数(48)。
|
||||
Size384 = 48
|
||||
// Size512 是 SHA3-512 摘要的字节数(64)。
|
||||
Size512 = 64
|
||||
|
||||
// Rate224 是 SHA3-224 的海绵分组(rate)字节数(144)。
|
||||
Rate224 = 144
|
||||
// Rate256 是 SHA3-256 的海绵分组(rate)字节数(136)。
|
||||
Rate256 = 136
|
||||
// Rate384 是 SHA3-384 的海绵分组(rate)字节数(104)。
|
||||
Rate384 = 104
|
||||
// Rate512 是 SHA3-512 的海绵分组(rate)字节数(72)。
|
||||
Rate512 = 72
|
||||
|
||||
// MaxShakeOutputLength 是 SHAKE128/SHAKE256 单次允许请求的最大输出字节数(1 MiB)。
|
||||
MaxShakeOutputLength = 1 << 20
|
||||
)
|
||||
|
||||
// New224 返回一个计算 SHA3-224 摘要的 hash.Hash。
|
||||
func New224() hash.Hash {
|
||||
return sha3.New224()
|
||||
}
|
||||
|
||||
// SHA3-384 哈希
|
||||
func Sha3_384(src string) string {
|
||||
h := sha3.New384()
|
||||
h.Write([]byte(src))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
// New256 返回一个计算 SHA3-256 摘要的 hash.Hash。
|
||||
func New256() hash.Hash {
|
||||
return sha3.New256()
|
||||
}
|
||||
|
||||
// SHA3-512 哈希
|
||||
func Sha3_512(src string) string {
|
||||
h := sha3.New512()
|
||||
h.Write([]byte(src))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
// New384 返回一个计算 SHA3-384 摘要的 hash.Hash。
|
||||
func New384() hash.Hash {
|
||||
return sha3.New384()
|
||||
}
|
||||
|
||||
// SHAKE128 可变长度哈希
|
||||
func Shake128(src string, outputLength int) string {
|
||||
h := sha3.NewShake128()
|
||||
h.Write([]byte(src))
|
||||
output := make([]byte, outputLength)
|
||||
h.Read(output)
|
||||
return hex.EncodeToString(output)
|
||||
// New512 返回一个计算 SHA3-512 摘要的 hash.Hash。
|
||||
func New512() hash.Hash {
|
||||
return sha3.New512()
|
||||
}
|
||||
|
||||
// SHAKE256 可变长度哈希
|
||||
func Shake256(src string, outputLength int) string {
|
||||
h := sha3.NewShake256()
|
||||
h.Write([]byte(src))
|
||||
output := make([]byte, outputLength)
|
||||
h.Read(output)
|
||||
return hex.EncodeToString(output)
|
||||
// New 等价于 New256。
|
||||
func New() hash.Hash {
|
||||
return New256()
|
||||
}
|
||||
|
||||
// NewShake128 返回一个 SHAKE128 XOF 实例,可流式 Write 输入后按需 Read 任意长度输出。
|
||||
// 调用方需自行保证输出长度合理(参见 MaxShakeOutputLength)。
|
||||
func NewShake128() sha3.ShakeHash {
|
||||
return sha3.NewShake128()
|
||||
}
|
||||
|
||||
// NewShake256 返回一个 SHAKE256 XOF 实例,可流式 Write 输入后按需 Read 任意长度输出。
|
||||
// 调用方需自行保证输出长度合理(参见 MaxShakeOutputLength)。
|
||||
func NewShake256() sha3.ShakeHash {
|
||||
return sha3.NewShake256()
|
||||
}
|
||||
|
||||
// Sum224 返回 data 的 SHA3-224 摘要(Size224 字节原始数据)。
|
||||
func Sum224(data []byte) []byte {
|
||||
return sum(sha3.New224(), data)
|
||||
}
|
||||
|
||||
// Sum256 返回 data 的 SHA3-256 摘要(Size256 字节原始数据)。
|
||||
func Sum256(data []byte) []byte {
|
||||
return sum(sha3.New256(), data)
|
||||
}
|
||||
|
||||
// Sum384 返回 data 的 SHA3-384 摘要(Size384 字节原始数据)。
|
||||
func Sum384(data []byte) []byte {
|
||||
return sum(sha3.New384(), data)
|
||||
}
|
||||
|
||||
// Sum512 返回 data 的 SHA3-512 摘要(Size512 字节原始数据)。
|
||||
func Sum512(data []byte) []byte {
|
||||
return sum(sha3.New512(), data)
|
||||
}
|
||||
|
||||
// Sum 等价于 Sum256。
|
||||
func Sum(data []byte) []byte {
|
||||
return Sum256(data)
|
||||
}
|
||||
|
||||
// Hex224 返回 data 的 SHA3-224 摘要的小写十六进制字符串。
|
||||
func Hex224(data []byte) string {
|
||||
return hex.EncodeToString(Sum224(data))
|
||||
}
|
||||
|
||||
// Hex256 返回 data 的 SHA3-256 摘要的小写十六进制字符串。
|
||||
func Hex256(data []byte) string {
|
||||
return hex.EncodeToString(Sum256(data))
|
||||
}
|
||||
|
||||
// Hex384 返回 data 的 SHA3-384 摘要的小写十六进制字符串。
|
||||
func Hex384(data []byte) string {
|
||||
return hex.EncodeToString(Sum384(data))
|
||||
}
|
||||
|
||||
// Hex512 返回 data 的 SHA3-512 摘要的小写十六进制字符串。
|
||||
func Hex512(data []byte) string {
|
||||
return hex.EncodeToString(Sum512(data))
|
||||
}
|
||||
|
||||
// Hex 等价于 Hex256。
|
||||
func Hex(data []byte) string {
|
||||
return Hex256(data)
|
||||
}
|
||||
|
||||
// Base64Sum224 返回 data 的 SHA3-224 摘要的标准 Base64 字符串。
|
||||
func Base64Sum224(data []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(Sum224(data))
|
||||
}
|
||||
|
||||
// Base64Sum256 返回 data 的 SHA3-256 摘要的标准 Base64 字符串。
|
||||
func Base64Sum256(data []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(Sum256(data))
|
||||
}
|
||||
|
||||
// Base64Sum384 返回 data 的 SHA3-384 摘要的标准 Base64 字符串。
|
||||
func Base64Sum384(data []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(Sum384(data))
|
||||
}
|
||||
|
||||
// Base64Sum512 返回 data 的 SHA3-512 摘要的标准 Base64 字符串。
|
||||
func Base64Sum512(data []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(Sum512(data))
|
||||
}
|
||||
|
||||
// Base64 等价于 Base64Sum256。
|
||||
func Base64(data []byte) string {
|
||||
return Base64Sum256(data)
|
||||
}
|
||||
|
||||
// Sum224Reader 读取 r 中的全部数据并返回其 SHA3-224 摘要。
|
||||
func Sum224Reader(r io.Reader) ([]byte, error) {
|
||||
return sumReader(sha3.New224(), r)
|
||||
}
|
||||
|
||||
// Sum256Reader 读取 r 中的全部数据并返回其 SHA3-256 摘要。
|
||||
func Sum256Reader(r io.Reader) ([]byte, error) {
|
||||
return sumReader(sha3.New256(), r)
|
||||
}
|
||||
|
||||
// Sum384Reader 读取 r 中的全部数据并返回其 SHA3-384 摘要。
|
||||
func Sum384Reader(r io.Reader) ([]byte, error) {
|
||||
return sumReader(sha3.New384(), r)
|
||||
}
|
||||
|
||||
// Sum512Reader 读取 r 中的全部数据并返回其 SHA3-512 摘要。
|
||||
func Sum512Reader(r io.Reader) ([]byte, error) {
|
||||
return sumReader(sha3.New512(), r)
|
||||
}
|
||||
|
||||
// SumReader 等价于 Sum256Reader。
|
||||
func SumReader(r io.Reader) ([]byte, error) {
|
||||
return Sum256Reader(r)
|
||||
}
|
||||
|
||||
// Hex224Reader 读取 r 中的全部数据并返回其 SHA3-224 摘要的小写十六进制字符串。
|
||||
func Hex224Reader(r io.Reader) (string, error) {
|
||||
return hexReader(sha3.New224(), r)
|
||||
}
|
||||
|
||||
// Hex256Reader 读取 r 中的全部数据并返回其 SHA3-256 摘要的小写十六进制字符串。
|
||||
func Hex256Reader(r io.Reader) (string, error) {
|
||||
return hexReader(sha3.New256(), r)
|
||||
}
|
||||
|
||||
// Hex384Reader 读取 r 中的全部数据并返回其 SHA3-384 摘要的小写十六进制字符串。
|
||||
func Hex384Reader(r io.Reader) (string, error) {
|
||||
return hexReader(sha3.New384(), r)
|
||||
}
|
||||
|
||||
// Hex512Reader 读取 r 中的全部数据并返回其 SHA3-512 摘要的小写十六进制字符串。
|
||||
func Hex512Reader(r io.Reader) (string, error) {
|
||||
return hexReader(sha3.New512(), r)
|
||||
}
|
||||
|
||||
// HexReader 等价于 Hex256Reader。
|
||||
func HexReader(r io.Reader) (string, error) {
|
||||
return Hex256Reader(r)
|
||||
}
|
||||
|
||||
// HexFile224 计算 path 所指向文件的 SHA3-224 摘要并返回小写十六进制字符串。
|
||||
func HexFile224(path string) (string, error) {
|
||||
return hexFile(path, "SHA3-224", sha3.New224)
|
||||
}
|
||||
|
||||
// HexFile256 计算 path 所指向文件的 SHA3-256 摘要并返回小写十六进制字符串。
|
||||
func HexFile256(path string) (string, error) {
|
||||
return hexFile(path, "SHA3-256", sha3.New256)
|
||||
}
|
||||
|
||||
// HexFile384 计算 path 所指向文件的 SHA3-384 摘要并返回小写十六进制字符串。
|
||||
func HexFile384(path string) (string, error) {
|
||||
return hexFile(path, "SHA3-384", sha3.New384)
|
||||
}
|
||||
|
||||
// HexFile512 计算 path 所指向文件的 SHA3-512 摘要并返回小写十六进制字符串。
|
||||
func HexFile512(path string) (string, error) {
|
||||
return hexFile(path, "SHA3-512", sha3.New512)
|
||||
}
|
||||
|
||||
// HexFile 等价于 HexFile256。
|
||||
func HexFile(path string) (string, error) {
|
||||
return HexFile256(path)
|
||||
}
|
||||
|
||||
// Shake128 返回 data 经 SHAKE128 扩展后的 outputLength 字节输出。
|
||||
// outputLength 必须大于 0 且不超过 MaxShakeOutputLength,否则返回 error。
|
||||
func Shake128(data []byte, outputLength int) ([]byte, error) {
|
||||
return shakeSum(sha3.NewShake128(), data, outputLength)
|
||||
}
|
||||
|
||||
// Shake256 返回 data 经 SHAKE256 扩展后的 outputLength 字节输出。
|
||||
// outputLength 必须大于 0 且不超过 MaxShakeOutputLength,否则返回 error。
|
||||
func Shake256(data []byte, outputLength int) ([]byte, error) {
|
||||
return shakeSum(sha3.NewShake256(), data, outputLength)
|
||||
}
|
||||
|
||||
// Shake128Hex 返回 data 经 SHAKE128 扩展后的 outputLength 字节输出的小写十六进制字符串。
|
||||
// outputLength 必须大于 0 且不超过 MaxShakeOutputLength,否则返回 error。
|
||||
func Shake128Hex(data []byte, outputLength int) (string, error) {
|
||||
out, err := Shake128(data, outputLength)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(out), nil
|
||||
}
|
||||
|
||||
// Shake256Hex 返回 data 经 SHAKE256 扩展后的 outputLength 字节输出的小写十六进制字符串。
|
||||
// outputLength 必须大于 0 且不超过 MaxShakeOutputLength,否则返回 error。
|
||||
func Shake256Hex(data []byte, outputLength int) (string, error) {
|
||||
out, err := Shake256(data, outputLength)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(out), nil
|
||||
}
|
||||
|
||||
// Shake128Reader 读取 r 中的全部数据并返回其 SHAKE128 扩展的 outputLength 字节输出。
|
||||
// outputLength 必须大于 0 且不超过 MaxShakeOutputLength,否则返回 error。
|
||||
func Shake128Reader(r io.Reader, outputLength int) ([]byte, error) {
|
||||
return shakeSumReader(sha3.NewShake128(), r, outputLength)
|
||||
}
|
||||
|
||||
// Shake256Reader 读取 r 中的全部数据并返回其 SHAKE256 扩展的 outputLength 字节输出。
|
||||
// outputLength 必须大于 0 且不超过 MaxShakeOutputLength,否则返回 error。
|
||||
func Shake256Reader(r io.Reader, outputLength int) ([]byte, error) {
|
||||
return shakeSumReader(sha3.NewShake256(), r, outputLength)
|
||||
}
|
||||
|
||||
// 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("sha3x: 读取器为 nil")
|
||||
}
|
||||
if _, err := io.Copy(h, r); err != nil {
|
||||
return nil, fmt.Errorf("sha3x: 读取数据失败: %w", err)
|
||||
}
|
||||
return h.Sum(nil), nil
|
||||
}
|
||||
|
||||
// hexReader 读取 r 的全部内容并以小写十六进制返回摘要。
|
||||
func hexReader(h hash.Hash, r io.Reader) (string, error) {
|
||||
sum, err := sumReader(h, r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(sum), nil
|
||||
}
|
||||
|
||||
// hexFile 计算文件的小写十六进制摘要,name 仅用于错误信息。
|
||||
func hexFile(path, name string, newHash func() hash.Hash) (string, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("sha3x: 打开文件 %q 失败: %w", path, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
sum, err := sumReader(newHash(), f)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("sha3x: 计算文件 %q 的 %s 摘要失败: %w", path, name, err)
|
||||
}
|
||||
return hex.EncodeToString(sum), nil
|
||||
}
|
||||
|
||||
// checkShakeLength 校验 XOF 输出长度是否在允许范围内。
|
||||
func checkShakeLength(outputLength int) error {
|
||||
if outputLength <= 0 {
|
||||
return fmt.Errorf("sha3x: SHAKE 输出长度必须大于 0,当前为 %d", outputLength)
|
||||
}
|
||||
if outputLength > MaxShakeOutputLength {
|
||||
return fmt.Errorf("sha3x: SHAKE 输出长度 %d 超过上限 %d", outputLength, MaxShakeOutputLength)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// readShake 从已写入输入的 XOF 中精确读取 outputLength 字节。
|
||||
func readShake(h sha3.ShakeHash, outputLength int) ([]byte, error) {
|
||||
if err := checkShakeLength(outputLength); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]byte, outputLength)
|
||||
if _, err := io.ReadFull(h, out); err != nil {
|
||||
return nil, fmt.Errorf("sha3x: 读取 SHAKE 输出失败: %w", err)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// shakeSum 计算 data 的 XOF 输出。
|
||||
func shakeSum(h sha3.ShakeHash, data []byte, outputLength int) ([]byte, error) {
|
||||
if err := checkShakeLength(outputLength); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := h.Write(data); err != nil {
|
||||
return nil, fmt.Errorf("sha3x: 写入 SHAKE 输入失败: %w", err)
|
||||
}
|
||||
return readShake(h, outputLength)
|
||||
}
|
||||
|
||||
// shakeSumReader 计算 r 全部内容的 XOF 输出。
|
||||
func shakeSumReader(h sha3.ShakeHash, r io.Reader, outputLength int) ([]byte, error) {
|
||||
if r == nil {
|
||||
return nil, fmt.Errorf("sha3x: 读取器为 nil")
|
||||
}
|
||||
if err := checkShakeLength(outputLength); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := io.Copy(h, r); err != nil {
|
||||
return nil, fmt.Errorf("sha3x: 读取数据失败: %w", err)
|
||||
}
|
||||
return readShake(h, outputLength)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user