From 30ddec340922ffda602b511dbdb0b95f31663004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Tue, 7 Oct 2025 22:38:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(hash):=20=E6=B7=BB=E5=8A=A0=20BLAKE3=20?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E5=92=8C=E7=AE=97=E6=B3=95=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 `README.md` 中将 BLAKE3 校验和算法标记为已完成 - 引入 `lukechampine.com/blake3` 依赖以实现 BLAKE3 算法功能 - 新增 `hash/blake3` 包,提供多种 BLAKE3 哈希计算函数 - 支持 BLAKE3、BLAKE3/224、BLAKE3/256、BLAKE3/384 等变种 - 提供字节数组与文件的哈希计算及十六进制编码结果 - 更新 `go.mod` 和 `go.sum` 以包含新增依赖项 --- README.md | 2 +- go.mod | 2 + go.sum | 4 ++ hash/blake3/blake3.go | 112 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 hash/blake3/blake3.go diff --git a/README.md b/README.md index efb192c..6a8593d 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Golang 中可以使用的常用辅助功能工具箱。主要配备以下功能 - [x] CRC64 校验和算法(便捷封装) - [x] pHash 图像感知算法(便捷封装) - [x] BLAKE2b 校验和算法(便捷封装) - - [ ] BLAKE3 校验和算法(便捷封装) + - [x] BLAKE3 校验和算法(便捷封装) - [ ] BlockHash 散列算法 - 唯一序列号生成器 - [x] 冰雹 ID 生成器(短主机精简日期版雪花 ID) diff --git a/go.mod b/go.mod index b3d19f8..6573005 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require go.uber.org/zap v1.24.0 require ( github.com/azr/gift v1.1.2 // indirect github.com/disintegration/imaging v1.6.2 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 // indirect golang.org/x/sys v0.36.0 // indirect ) @@ -19,4 +20,5 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/crypto v0.42.0 + lukechampine.com/blake3 v1.4.1 ) diff --git a/go.sum b/go.sum index 9d07ea2..32fbe7b 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6 h1:IIVxLyDUYErC950b8kecjoqDet8P5S4lcVRUOM6rdkU= github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6/go.mod h1:JslaLRrzGsOKJgFEPBP65Whn+rdwDQSk0I0MCRFe2Zw= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f h1:1R9KdKjCNSd7F8iGTxIpoID9prlYH8nuNYKt0XvweHA= github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f/go.mod h1:vQhwQ4meQEDfahT5kd61wLAF5AAeh5ZPLVI4JJ/tYo8= @@ -31,3 +33,5 @@ golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= +lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= diff --git a/hash/blake3/blake3.go b/hash/blake3/blake3.go new file mode 100644 index 0000000..ab26ee5 --- /dev/null +++ b/hash/blake3/blake3.go @@ -0,0 +1,112 @@ +// 提供Blake3系列散列算法函数和校验和函数。 +package blake3 + +import ( + "encoding/hex" + "fmt" + "hash" + "io" + "os" + + "lukechampine.com/blake3" +) + +// 根据给定的位数返回一个散列算法的Hash实例。 +func hasherSelect(bitSize int) hash.Hash { + switch bitSize { + case 224: + return blake3.New(28, nil) + case 256: + return blake3.New(32, nil) + case 384: + return blake3.New(48, nil) + case 512: + return blake3.New(64, nil) + default: + return blake3.New(32, nil) + } +} + +// 计算给定字节数组的Blake3校验和,返回字节数组。 +func Blake3(data []byte) []byte { + hasher := hasherSelect(512) + hasher.Write(data) + return hasher.Sum(nil) +} + +// 计算给定字节数组的Blake3/256校验和,返回字节数组。 +func Blake3_256(data []byte) []byte { + hasher := hasherSelect(256) + hasher.Write(data) + return hasher.Sum(nil) +} + +// 计算给定字节数组的Blake3/384校验和,返回字节数组。 +func Blake3_384(data []byte) []byte { + hasher := hasherSelect(384) + hasher.Write(data) + return hasher.Sum(nil) +} + +// 计算给定字节数组的Blake3/224校验和,返回字节数组。 +func Blake3_224(data []byte) []byte { + hasher := hasherSelect(224) + hasher.Write(data) + return hasher.Sum(nil) +} + +// 计算给定字节数组的Blake3校验和,返回十六进制字符串。 +func Blake3Hex(data []byte) string { + return hex.EncodeToString(Blake3(data)) +} + +// 计算给定字节数组的Blake3/256校验和,返回十六进制字符串。 +func Blake3_256Hex(data []byte) string { + return hex.EncodeToString(Blake3_256(data)) +} + +// 计算给定字节数组的Blake3/384校验和,返回十六进制字符串。 +func Blake3_384Hex(data []byte) string { + return hex.EncodeToString(Blake3_384(data)) +} + +// 计算给定字节数组的Blake3/224校验和,返回十六进制字符串。 +func Blake3_224Hex(data []byte) string { + return hex.EncodeToString(Blake3_224(data)) +} + +// 根据给定位数计算一个字节数组的Blake3校验和,返回字节数组。 +func Sum(data []byte, bitSize ...int) []byte { + hasher := hasherSelect(append(bitSize, 512)[0]) + hasher.Write(data) + return hasher.Sum(nil) +} + +// 根据给定位数计算一个字节数组的Blake3校验和,返回十六进制字符串。 +func SumHex(data []byte, bitSize ...int) string { + return hex.EncodeToString(Sum(data, bitSize...)) +} + +// 根据给定位数计算一个文件的Blake3校验和,返回字节数组。 +func SumFile(file string, bitSize ...int) ([]byte, error) { + f, err := os.Open(file) + if err != nil { + return nil, fmt.Errorf("未能打开指定文件,%w", err) + } + defer f.Close() + + hasher := hasherSelect(append(bitSize, 512)[0]) + if _, err := io.Copy(hasher, f); err != nil { + return nil, fmt.Errorf("未能读取指定文件的内容,%w", err) + } + return hasher.Sum(nil), nil +} + +// 根据给定位数计算一个文件的Blake3校验和,返回十六进制字符串。 +func SumFileHex(file string, bitSize ...int) (string, error) { + hash, err := SumFile(file, bitSize...) + if err != nil { + return "", err + } + return hex.EncodeToString(hash), nil +} \ No newline at end of file