From 2a2283ec4ca022d4c5f21de269f4568c0cd60ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Wed, 12 Jul 2023 15:26:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(hash):=E5=A2=9E=E5=8A=A0pHash=E5=9B=BE?= =?UTF-8?q?=E5=83=8F=E6=84=9F=E7=9F=A5=E5=93=88=E5=B8=8C=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- go.mod | 7 +++++++ go.sum | 12 ++++++++++++ hash/phash/phash.go | 48 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 hash/phash/phash.go diff --git a/README.md b/README.md index 94c883d..779d452 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ Golang 中可以使用的常用辅助功能工具箱。主要配备以下功能 - [x] CRC16 校验和算法 - [x] CRC32 校验和算法 - [x] CRC64 校验和算法 - - [ ] 图像感知散列算法 + - [x] pHash 图像感知算法 + - [ ] BlockHash 散列算法 - 唯一序列号生成器 - [ ] 冰雹 ID 生成器(短主机精简日期版雪花 ID) - [ ] UUID 生成器 diff --git a/go.mod b/go.mod index 728de1b..500b245 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,13 @@ go 1.20 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 + golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 // indirect +) + +require ( + github.com/azr/phash v0.2.0 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 diff --git a/go.sum b/go.sum index e9fc0b0..7791834 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,11 @@ +github.com/azr/gift v1.1.2 h1:EbQ8/1QMtDfz5Beqg+RY5F21KbwGhE8aWSEbF1pp95A= +github.com/azr/gift v1.1.2/go.mod h1:bDKvjyxgachY3zdk831G99y+VANype25eu37uhm3khI= +github.com/azr/phash v0.2.0 h1:F6qkeYlwuMUMkUAJkQFElGrQzFnneJwV+L23VrEQ0cU= +github.com/azr/phash v0.2.0/go.mod h1:vUennaUN3i09UA33YxHpCR5l2CeENoCRB2Jo6pvWNf4= 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/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= 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= @@ -13,3 +19,9 @@ go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 h1:/eM0PCrQI2xd471rI+snWuu251/+/jpBpZqir2mPdnU= +golang.org/x/image v0.0.0-20220722155232-062f8c9fd539/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY= +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= diff --git a/hash/phash/phash.go b/hash/phash/phash.go new file mode 100644 index 0000000..c173619 --- /dev/null +++ b/hash/phash/phash.go @@ -0,0 +1,48 @@ +// 提供图像感知哈希算法功能(pHash)。 +package phash + +import ( + "encoding/binary" + "encoding/hex" + "image" + "os" + + "github.com/azr/phash" +) + +// 计算图像的感知哈希值,并返回字节数组。 +func Hash(image image.Image) []byte { + var bashBytes = make([]byte, 8) + hash := phash.DTC(image) + binary.BigEndian.PutUint64(bashBytes, hash) + return bashBytes +} + +// 计算图像的感知哈希值,并返回十六进制字符串。 +func HashHex(image image.Image) string { + return hex.EncodeToString(Hash(image)) +} + +// 计算指定图像文件的感知哈希值,并返回字节数组。 +func HashFile(file string) ([]byte, error) { + f, err := os.Open(file) + if err != nil { + return nil, err + } + defer f.Close() + + img, _, err := image.Decode(f) + if err != nil { + return nil, err + } + return Hash(img), nil +} + +// 计算指定图像文件的感知哈希值,并返回十六进制字符串。 +func HashFileHex(file string) (string, error) { + hash, err := HashFile(file) + if err != nil { + return "", err + } + return hex.EncodeToString(hash), nil +}