refactor: 重构trustlog-sdk目录结构到trustlog/go-trustlog
- 将所有trustlog-sdk文件移动到trustlog/go-trustlog/目录 - 更新README中所有import路径从trustlog-sdk改为go-trustlog - 更新cookiecutter配置文件中的项目名称 - 更新根目录.lefthook.yml以引用新位置的配置 - 添加go.sum文件到版本控制 - 删除过时的示例文件 这次重构与trustlog-server保持一致的目录结构, 为未来支持多语言SDK(Python、Java等)预留空间。
This commit is contained in:
267
api/model/hash.go
Normal file
267
api/model/hash.go
Normal file
@@ -0,0 +1,267 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
stdsha256 "crypto/sha256"
|
||||
stdsha512 "crypto/sha512"
|
||||
"encoding/hex"
|
||||
"hash"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
miniosha256 "github.com/minio/sha256-simd"
|
||||
"github.com/zeebo/blake3"
|
||||
"golang.org/x/crypto/blake2b"
|
||||
"golang.org/x/crypto/blake2s"
|
||||
"golang.org/x/crypto/md4" //nolint:staticcheck // 保留弱加密算法以支持遗留系统兼容性
|
||||
"golang.org/x/crypto/ripemd160" //nolint:staticcheck // 保留弱加密算法以支持遗留系统兼容性
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
// HashType 定义支持的哈希算法类型.
|
||||
type HashType string
|
||||
|
||||
const (
|
||||
MD5 HashType = "md5"
|
||||
SHA1 HashType = "sha1"
|
||||
SHA224 HashType = "sha224"
|
||||
SHA256 HashType = "sha256"
|
||||
SHA384 HashType = "sha384"
|
||||
SHA512 HashType = "sha512"
|
||||
Sha512224 HashType = "sha512_224"
|
||||
Sha512256 HashType = "sha512_256"
|
||||
|
||||
Sha256Simd HashType = "sha256-simd"
|
||||
BLAKE3 HashType = "blake3"
|
||||
BLAKE2B HashType = "blake2b"
|
||||
BLAKE2S HashType = "blake2s"
|
||||
MD4 HashType = "md4"
|
||||
RIPEMD160 HashType = "ripemd160"
|
||||
Sha3224 HashType = "sha3-224"
|
||||
Sha3256 HashType = "sha3-256"
|
||||
Sha3384 HashType = "sha3-384"
|
||||
Sha3512 HashType = "sha3-512"
|
||||
)
|
||||
|
||||
// 使用 map 来存储支持的算法,提高查找效率.
|
||||
//
|
||||
//nolint:gochecknoglobals // 全局缓存用于算法查找和实例复用.
|
||||
var (
|
||||
supportedAlgorithms []string
|
||||
supportedAlgorithmsMap map[string]bool
|
||||
supportedAlgorithmsOnce sync.Once
|
||||
|
||||
// 享元模式:存储已创建的 HashTool 实例.
|
||||
toolPool = make(map[HashType]*HashTool)
|
||||
poolMutex sync.RWMutex
|
||||
)
|
||||
|
||||
// HashTool 哈希工具类.
|
||||
type HashTool struct {
|
||||
hashType HashType
|
||||
}
|
||||
|
||||
// GetHashTool 获取指定类型的 HashTool.
|
||||
func GetHashTool(hashType HashType) *HashTool {
|
||||
poolMutex.RLock()
|
||||
if tool, exists := toolPool[hashType]; exists {
|
||||
poolMutex.RUnlock()
|
||||
return tool
|
||||
}
|
||||
poolMutex.RUnlock()
|
||||
|
||||
poolMutex.Lock()
|
||||
defer poolMutex.Unlock()
|
||||
|
||||
if tool, exists := toolPool[hashType]; exists {
|
||||
return tool
|
||||
}
|
||||
|
||||
tool := &HashTool{hashType: hashType}
|
||||
toolPool[hashType] = tool
|
||||
return tool
|
||||
}
|
||||
|
||||
// NewHashTool 创建新的哈希工具实例.
|
||||
func NewHashTool(hashType HashType) *HashTool {
|
||||
return &HashTool{hashType: hashType}
|
||||
}
|
||||
|
||||
// getHasher 根据哈希类型获取对应的哈希器.
|
||||
func (h *HashTool) getHasher() hash.Hash {
|
||||
switch h.hashType {
|
||||
case MD5:
|
||||
return md5.New()
|
||||
case SHA1:
|
||||
return sha1.New()
|
||||
case SHA224:
|
||||
return stdsha256.New224()
|
||||
case SHA256:
|
||||
return stdsha256.New()
|
||||
case SHA384:
|
||||
return stdsha512.New384()
|
||||
case SHA512:
|
||||
return stdsha512.New()
|
||||
case Sha512224:
|
||||
return stdsha512.New512_224()
|
||||
case Sha512256:
|
||||
return stdsha512.New512_256()
|
||||
|
||||
// 第三方算法
|
||||
case Sha256Simd:
|
||||
return miniosha256.New()
|
||||
case BLAKE3:
|
||||
return blake3.New()
|
||||
case BLAKE2B:
|
||||
hasher, _ := blake2b.New512(nil)
|
||||
return hasher
|
||||
case BLAKE2S:
|
||||
hasher, _ := blake2s.New256(nil)
|
||||
return hasher
|
||||
case MD4:
|
||||
return md4.New()
|
||||
case RIPEMD160:
|
||||
return ripemd160.New()
|
||||
case Sha3224:
|
||||
return sha3.New224()
|
||||
case Sha3256:
|
||||
return sha3.New256()
|
||||
case Sha3384:
|
||||
return sha3.New384()
|
||||
case Sha3512:
|
||||
return sha3.New512()
|
||||
|
||||
default:
|
||||
return stdsha256.New() // 默认使用 SHA256
|
||||
}
|
||||
}
|
||||
|
||||
// hashData 通用的哈希计算函数.
|
||||
func (h *HashTool) hashData(processFunc func(hasher hash.Hash) error) (string, error) {
|
||||
hasher := h.getHasher()
|
||||
if err := processFunc(hasher); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(hasher.Sum(nil)), nil
|
||||
}
|
||||
|
||||
// HashString 对字符串进行哈希计算.
|
||||
func (h *HashTool) HashString(data string) (string, error) {
|
||||
return h.hashData(func(hasher hash.Hash) error {
|
||||
_, err := hasher.Write([]byte(data))
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// HashBytes 对字节数组进行哈希计算.
|
||||
func (h *HashTool) HashBytes(data []byte) (string, error) {
|
||||
return h.hashData(func(hasher hash.Hash) error {
|
||||
_, err := hasher.Write(data)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// HashBytesRaw 对字节数组进行哈希计算,返回原始字节数组(非hex字符串).
|
||||
func (h *HashTool) HashBytesRaw(data []byte) ([]byte, error) {
|
||||
hasher := h.getHasher()
|
||||
if _, err := hasher.Write(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hasher.Sum(nil), nil
|
||||
}
|
||||
|
||||
// HashFile 对文件进行哈希计算.
|
||||
func (h *HashTool) HashFile(_ context.Context, filePath string) (string, error) {
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
return h.hashData(func(hasher hash.Hash) error {
|
||||
_, copyErr := io.Copy(hasher, file)
|
||||
return copyErr
|
||||
})
|
||||
}
|
||||
|
||||
// HashStream 对流数据进行哈希计算.
|
||||
func (h *HashTool) HashStream(reader io.Reader) (string, error) {
|
||||
return h.hashData(func(hasher hash.Hash) error {
|
||||
_, err := io.Copy(hasher, reader)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// initSupportedAlgorithms 初始化支持的算法数据.
|
||||
func initSupportedAlgorithms() {
|
||||
algorithms := []HashType{
|
||||
MD5, SHA1, SHA224, SHA256, SHA384, SHA512,
|
||||
Sha512224, Sha512256, Sha256Simd, BLAKE3,
|
||||
BLAKE2B, BLAKE2S, MD4, RIPEMD160,
|
||||
Sha3224, Sha3256, Sha3384, Sha3512,
|
||||
}
|
||||
|
||||
supportedAlgorithms = make([]string, len(algorithms))
|
||||
supportedAlgorithmsMap = make(map[string]bool, len(algorithms))
|
||||
|
||||
for i, alg := range algorithms {
|
||||
algStr := string(alg)
|
||||
supportedAlgorithms[i] = algStr
|
||||
supportedAlgorithmsMap[strings.ToLower(algStr)] = true
|
||||
}
|
||||
}
|
||||
|
||||
// GetSupportedAlgorithms 获取支持的哈希算法列表.
|
||||
func GetSupportedAlgorithms() []string {
|
||||
supportedAlgorithmsOnce.Do(initSupportedAlgorithms)
|
||||
return supportedAlgorithms
|
||||
}
|
||||
|
||||
// IsAlgorithmSupported 检查算法是否支持 - 使用 map 提高性能.
|
||||
func IsAlgorithmSupported(algorithm string) bool {
|
||||
supportedAlgorithmsOnce.Do(initSupportedAlgorithms)
|
||||
return supportedAlgorithmsMap[strings.ToLower(algorithm)]
|
||||
}
|
||||
|
||||
// CompareHash 比较哈希值.
|
||||
func (h *HashTool) CompareHash(data, expectedHash string) (bool, error) {
|
||||
actualHash, err := h.HashString(data)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return strings.EqualFold(actualHash, expectedHash), nil
|
||||
}
|
||||
|
||||
// CompareFileHash 比较文件哈希值.
|
||||
func (h *HashTool) CompareFileHash(ctx context.Context, filePath, expectedHash string) (bool, error) {
|
||||
actualHash, err := h.HashFile(ctx, filePath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return strings.EqualFold(actualHash, expectedHash), nil
|
||||
}
|
||||
|
||||
// GetHashType 获取当前工具使用的哈希类型.
|
||||
func (h *HashTool) GetHashType() HashType {
|
||||
return h.hashType
|
||||
}
|
||||
|
||||
type HashData interface {
|
||||
Key() string
|
||||
Hash() string
|
||||
Type() HashType
|
||||
}
|
||||
|
||||
type Hashable interface {
|
||||
DoHash(ctx context.Context) (HashData, error)
|
||||
}
|
||||
|
||||
type HashList []HashData
|
||||
|
||||
func (h HashList) GetHashType() HashType {
|
||||
return h[0].Type()
|
||||
}
|
||||
Reference in New Issue
Block a user