feat(hash):增加系列校验和算法实现。

This commit is contained in:
徐涛 2023-07-12 14:59:25 +08:00
parent 0cbeaf050e
commit 29cebf455c
11 changed files with 543 additions and 5 deletions

View File

@ -21,11 +21,15 @@ Golang 中可以使用的常用辅助功能工具箱。主要配备以下功能
- [ ] 2048 位长
- [ ] KeyPair 生成器
- [ ] RSA 签名算法
- 散列算法。
- [ ] Sha512 散列算法
- [ ] Sha256 散列算法
- [ ] Sha1 散列算法
- [ ] MD5 散列算法
- 散列及校验和算法。
- [x] Sha512 散列算法
- [x] Sha256 散列算法
- [x] Sha1 散列算法
- [x] MD5 散列算法
- [x] CRC8 校验和算法
- [x] CRC16 校验和算法
- [x] CRC32 校验和算法
- [x] CRC64 校验和算法
- [ ] 图像感知散列算法
- 唯一序列号生成器
- [ ] 冰雹 ID 生成器(短主机精简日期版雪花 ID)

2
go.mod
View File

@ -5,6 +5,8 @@ go 1.20
require go.uber.org/zap v1.24.0
require (
github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6
github.com/sigurn/crc8 v0.0.0-20220107193325-2243fe600f9f
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
)

4
go.sum
View File

@ -1,6 +1,10 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/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=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=

66
hash/crc16/crc16.go Normal file
View File

@ -0,0 +1,66 @@
// 提供CRC16校验和计算功能。
package crc16
import (
"encoding/hex"
"io"
"os"
"github.com/howeyc/crc16"
)
// 根据给定的校验表类型生成对应的校验器
func hasherSelect(table string) crc16.Hash16 {
switch table {
case "CCITT":
return crc16.NewCCITT()
case "CCITT-FALSE":
return crc16.New(crc16.MakeTable(crc16.CCITTFalse))
case "SCSI":
return crc16.NewSCSI()
case "IBM":
return crc16.NewIBM()
case "MBUS":
return crc16.New(crc16.MakeTable(crc16.MBUS))
default:
return crc16.NewIBM()
}
}
// 计算给定字节数组的CRC16校验和返回字节数组
func CRC16(data []byte, table ...string) []byte {
crcTable := append(table, "IBM")
hasher := hasherSelect(crcTable[0])
hasher.Write(data)
return hasher.Sum(nil)
}
// 计算给定字节数组的CRC16校验和返回十六进制字符串
func CRC16Hex(data []byte, table ...string) string {
return hex.EncodeToString(CRC16(data, table...))
}
// 计算指定文件的CRC16校验和返回字节数组
func SumFile(file string, table ...string) ([]byte, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
crcTable := append(table, "IBM")
hasher := hasherSelect(crcTable[0])
if _, err := io.Copy(hasher, f); err != nil {
return nil, err
}
return hasher.Sum(nil), nil
}
// 计算指定文件的CRC16校验和返回十六进制字符串
func SumFileHex(file string, table ...string) (string, error) {
hash, err := SumFile(file, table...)
if err != nil {
return "", err
}
return hex.EncodeToString(hash), nil
}

61
hash/crc32/crc32.go Normal file
View File

@ -0,0 +1,61 @@
// 提供CRC32校验和计算功能
package crc32
import (
"encoding/hex"
"hash/crc32"
"io"
"os"
)
// 选择一个CRC32校验表
func tableSelect(table string) *crc32.Table {
switch table {
case "IEEE":
return crc32.IEEETable
case "Castagnoli":
return crc32.MakeTable(crc32.Castagnoli)
case "Koopman":
return crc32.MakeTable(crc32.Koopman)
default:
return crc32.IEEETable
}
}
// 计算给定字节数组的CRC32校验和返回字节数组
func CRC32(data []byte, table ...string) []byte {
crcTable := append(table, "IEEE")
hasher := crc32.New(tableSelect(crcTable[0]))
hasher.Write(data)
return hasher.Sum(nil)
}
// 计算给定字节数组的CRC32校验和返回十六进制字符串
func CRC32Hex(data []byte, table ...string) string {
return hex.EncodeToString(CRC32(data, table...))
}
// 计算指定文件的CRC32校验和返回字节数组
func SumFile(file string, table ...string) ([]byte, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
crcTable := append(table, "IEEE")
hasher := crc32.New(tableSelect(crcTable[0]))
if _, err := io.Copy(hasher, f); err != nil {
return nil, err
}
return hasher.Sum(nil), nil
}
// 计算指定文件的CRC32校验和返回十六进制字符串
func SumFileHex(file string, table ...string) (string, error) {
hash, err := SumFile(file, table...)
if err != nil {
return "", err
}
return hex.EncodeToString(hash), nil
}

59
hash/crc64/crc64.go Normal file
View File

@ -0,0 +1,59 @@
// 提供CRC64校验和计算功能。
package crc64
import (
"encoding/hex"
"hash/crc64"
"io"
"os"
)
// 选择一个CRC64校验表。
func tableSelect(table string) *crc64.Table {
switch table {
case "ECMA":
return crc64.MakeTable(crc64.ECMA)
case "ISO":
return crc64.MakeTable(crc64.ISO)
default:
return crc64.MakeTable(crc64.ISO)
}
}
// 计算给定字节数组的CRC64校验和返回字节数组。
func CRC64(data []byte, table ...string) []byte {
crcTable := append(table, "ISO")
hasher := crc64.New(tableSelect(crcTable[0]))
hasher.Write(data)
return hasher.Sum(nil)
}
// 计算给定字节数组的CRC64校验和返回十六进制字符串。
func CRC64Hex(data []byte, table ...string) string {
return hex.EncodeToString(CRC64(data, table...))
}
// 计算一个指定文件的CRC64校验和返回字节数组。
func SumFile(file string, table ...string) ([]byte, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
crcTable := append(table, "ISO")
hasher := crc64.New(tableSelect(crcTable[0]))
if _, err := io.Copy(hasher, f); err != nil {
return nil, err
}
return hasher.Sum(nil), nil
}
// 计算一个指定文件的CRC64校验和返回十六进制字符串。
func SumFileHex(file string, table ...string) (string, error) {
hash, err := SumFile(file, table...)
if err != nil {
return "", err
}
return hex.EncodeToString(hash), nil
}

73
hash/crc8/crc8.go Normal file
View File

@ -0,0 +1,73 @@
// 提供CRC8校验和计算功能。
package crc8
import (
"encoding/hex"
"os"
"github.com/sigurn/crc8"
)
// 根据提供的校验表名称生成对应的校验表
func hasherSelect(table string) *crc8.Table {
switch table {
case "CRC8":
return crc8.MakeTable(crc8.CRC8)
case "CDMA2000":
return crc8.MakeTable(crc8.CRC8_CDMA2000)
case "DARC":
return crc8.MakeTable(crc8.CRC8_DARC)
case "DVB-S2":
return crc8.MakeTable(crc8.CRC8_DVB_S2)
case "EBU":
return crc8.MakeTable(crc8.CRC8_EBU)
case "I-CODE":
return crc8.MakeTable(crc8.CRC8_I_CODE)
case "ITU":
return crc8.MakeTable(crc8.CRC8_ITU)
case "MAXIM":
return crc8.MakeTable(crc8.CRC8_MAXIM)
case "ROHC":
return crc8.MakeTable(crc8.CRC8_ROHC)
case "WCDMA":
return crc8.MakeTable(crc8.CRC8_WCDMA)
default:
return crc8.MakeTable(crc8.CRC8)
}
}
// 计算给定字节数组的CRC8校验和返回字节数组
func CRC8(data []byte, table ...string) []byte {
crcTable := append(table, "CRC8")
return []byte{crc8.Checksum(data, hasherSelect(crcTable[0]))}
}
// 计算给定字节数组的CRC8校验和返回十六进制字符串
func CRC8Hex(data []byte, table ...string) string {
return hex.EncodeToString(CRC8(data, table...))
}
// 计算指定文件的CRC8校验和返回字节数组
func SumFile(file string, table ...string) ([]byte, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
crcTable := append(table, "CRC8")
var buf = make([]byte, 0)
if _, err := f.Read(buf); err != nil {
return nil, err
}
return []byte{crc8.Checksum(buf, hasherSelect(crcTable[0]))}, nil
}
// 计算指定文件的CRC8校验和返回十六进制字符串
func SumFileHex(file string, table ...string) (string, error) {
crc, err := SumFile(file, table...)
if err != nil {
return "", err
}
return hex.EncodeToString(crc), nil
}

45
hash/md5/md5.go Normal file
View File

@ -0,0 +1,45 @@
// 提供MD5散列算法的函数。
package md5
import (
"crypto/md5"
"encoding/hex"
"io"
"os"
)
// 计算给定字节数组的MD5校验和返回字节数组。
func MD5(data []byte) []byte {
hasher := md5.New()
hasher.Write(data)
return hasher.Sum(nil)
}
// 计算给定字节数组的MD5校验和返回十六进制字符串。
func MD5Hex(data []byte) string {
return hex.EncodeToString(MD5(data))
}
// 计算一个指定文件的MD5校验和返回字节数组。
func SumFile(file string) ([]byte, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
hasher := md5.New()
if _, err := io.Copy(hasher, f); err != nil {
return nil, err
}
return hasher.Sum(nil), nil
}
// 计算一个指定文件的MD5校验和返回十六进制字符串。
func SumFileHex(file string) (string, error) {
hash, err := SumFile(file)
if err != nil {
return "", err
}
return hex.EncodeToString(hash), nil
}

45
hash/sha1/sha1.go Normal file
View File

@ -0,0 +1,45 @@
// 提供Sha1系列散列算法函数和校验和函数
package sha1
import (
"crypto/sha1"
"encoding/hex"
"io"
"os"
)
// 计算给定字节数组的Sha1校验和返回字节数组
func Sha1(data []byte) []byte {
hasher := sha1.New()
hasher.Write(data)
return hasher.Sum(nil)
}
// 计算给定字节数组的Sha1校验和返回十六进制字符串
func Sha1Hex(data []byte) string {
return hex.EncodeToString(Sha1(data))
}
// 计算一个指定文件的Sha1校验和返回字节数组
func SumFile(file string) ([]byte, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
hasher := sha1.New()
if _, err := io.Copy(hasher, f); err != nil {
return nil, err
}
return hasher.Sum(nil), nil
}
// 计算一个指定文件的Sha1校验和返回十六进制字符串
func SumFileHex(file string) (string, error) {
hash, err := SumFile(file)
if err != nil {
return "", err
}
return hex.EncodeToString(hash), nil
}

81
hash/sha256/sha256.go Normal file
View File

@ -0,0 +1,81 @@
// 提供Sha256系列散列算法函数和校验和函数。
package sha256
import (
"crypto/sha256"
"encoding/hex"
"hash"
"io"
"os"
)
// 根据给定的位数返回一个散列算法的Hash实例。
func hasherSelect(bitSize int) hash.Hash {
switch bitSize {
case 224:
return sha256.New224()
default:
return sha256.New()
}
}
// 计算给定字节数组的Sha256校验和返回字节数组。
func Sha256(data []byte) []byte {
hasher := hasherSelect(256)
hasher.Write(data)
return hasher.Sum(nil)
}
// 计算给定字节数组的Sha256/224校验和返回字节数组。
func Sha256_224(data []byte) []byte {
hasher := hasherSelect(224)
hasher.Write(data)
return hasher.Sum(nil)
}
// 计算给定字节数组的Sha256校验和返回十六进制字符串。
func Sha256Hex(data []byte) string {
return hex.EncodeToString(Sha256(data))
}
// 计算给定字节数组的Sha256/224校验和返回十六进制字符串。
func Sha256_224Hex(data []byte) string {
return hex.EncodeToString(Sha256_224(data))
}
// 根据给定位数计算一个字节数组的Sha256校验和返回字节数组。
func Sum256(data []byte, bitSize ...int) []byte {
length := append(bitSize, 256)
hasher := hasherSelect(length[0])
hasher.Write(data)
return hasher.Sum(nil)
}
// 根据给定位数计算一个字节数组的Sha256校验和返回十六进制字符串。
func Sum256Hex(data []byte, bitSize ...int) string {
return hex.EncodeToString(Sum256(data, bitSize...))
}
// 根据给定位数计算一个文件的Sha256校验和返回字节数组。
func SumFile256(file string, bitSize ...int) ([]byte, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
hasher := hasherSelect(bitSize[0])
if _, err := io.Copy(hasher, f); err != nil {
return nil, err
}
return hasher.Sum(nil), nil
}
// 根据给定位数计算一个文件的Sha256校验和返回十六进制字符串。
func SumFile256Hex(file string, bitSize ...int) (string, error) {
hash, err := SumFile256(file, bitSize...)
if err != nil {
return "", err
}
return hex.EncodeToString(hash), nil
}

98
hash/sha512/sha512.go Normal file
View File

@ -0,0 +1,98 @@
// 提供Sha512系列散列算法函数和校验和函数。
package sha512
import (
"crypto/sha512"
"encoding/hex"
"hash"
"io"
"os"
)
// 根据给定的位数返回一个散列算法的Hash实例。
func hasherSelect(bitSize int) hash.Hash {
switch bitSize {
case 224:
return sha512.New512_224()
case 256:
return sha512.New512_256()
case 384:
return sha512.New384()
default:
return sha512.New()
}
}
// 计算给定字节数组的Sha512校验和返回字节数组。
func Sha512(data []byte) []byte {
hash := hasherSelect(512)
hash.Write(data)
return hash.Sum(nil)
}
// 计算给定字节数组的Sha512/384校验和返回字节数组。
func Sha512_384(data []byte) []byte {
hash := hasherSelect(384)
hash.Write(data)
return hash.Sum(nil)
}
// 计算给定字节数组的Sha512/256校验和返回字节数组。
func Sha512_256(data []byte) []byte {
hash := hasherSelect(256)
hash.Write(data)
return hash.Sum(nil)
}
// 计算给定字节数组的Sha512校验和返回十六进制字符串。
func Sha512Hex(data []byte) string {
return hex.EncodeToString(Sha512(data))
}
// 计算给定字节数组的Sha512/384校验和返回十六进制字符串。
func Sha512_384Hex(data []byte) string {
return hex.EncodeToString(Sha512_384(data))
}
// 计算给定字节数组的Sha512/256校验和返回十六进制字符串。
func Sha512_256Hex(data []byte) string {
return hex.EncodeToString(Sha512_256(data))
}
// 根据给定位数计算指定字节数组的校验和,返回字节数组。
func Sum512(data []byte, bitSize ...int) []byte {
length := append(bitSize, 512)
var hasher = hasherSelect(length[0])
hasher.Write(data)
return hasher.Sum(nil)
}
// 根据给定位数计算指定字节数组的校验和,返回十六进制字符串。
func Sum512Hex(data []byte, bitSize ...int) string {
return hex.EncodeToString(Sum512(data, bitSize...))
}
// 根据给定位数计算指定文件的校验和,返回字节数组。
func SumFile512(path string, bitSize ...int) ([]byte, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
length := append(bitSize, 512)
var hasher = hasherSelect(length[0])
if _, err := io.Copy(hasher, f); err != nil {
return nil, err
}
return hasher.Sum(nil), nil
}
// 根据给定位数计算指定文件的校验和,返回十六进制字符串。
func SumFile512Hex(path string, bitSize ...int) (string, error) {
data, err := SumFile512(path, bitSize...)
if err != nil {
return "", err
}
return hex.EncodeToString(data), nil
}