init commit
This commit is contained in:
commit
1cbaf88b29
181
.gitignore
vendored
Normal file
181
.gitignore
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
### Intellij template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### Intellij+all template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### Go template
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
11
.idea/$PROJECT_FILE$
Normal file
11
.idea/$PROJECT_FILE$
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AnalysisProjectProfileManager">
|
||||
<option name="PROJECT_PROFILE" />
|
||||
<option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
|
||||
<list size="0" />
|
||||
</component>
|
||||
<component name="SuppressionsComponent">
|
||||
<option name="suppComments" value="[]" />
|
||||
</component>
|
||||
</project>
|
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="CollectionsFieldAccessReplaceableByMethodCall" enabled="true" level="WEAK WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES" />
|
||||
</profile>
|
||||
</component>
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
</settings>
|
||||
</component>
|
12
assert/assertion.go
Normal file
12
assert/assertion.go
Normal file
@ -0,0 +1,12 @@
|
||||
package assert
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Equals[T any](t *testing.T, got, want T) {
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
errorf(t, "%s got %v, but want %v", t.Name(), got, want)
|
||||
}
|
||||
}
|
19
assert/log.go
Normal file
19
assert/log.go
Normal file
@ -0,0 +1,19 @@
|
||||
package assert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
_ "unsafe"
|
||||
)
|
||||
|
||||
// 指针接收器
|
||||
//
|
||||
//go:linkname logDepth testing.(*common).logDepth
|
||||
//go:nosplit
|
||||
func logDepth(_ *testing.T, s string, depth int)
|
||||
|
||||
func errorf(t *testing.T, format string, args ...any) {
|
||||
logDepth(t, fmt.Sprintf(format, args...), 3)
|
||||
t.Fail()
|
||||
}
|
32
checksum/adler32.go
Normal file
32
checksum/adler32.go
Normal file
@ -0,0 +1,32 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"hash"
|
||||
"hash/adler32"
|
||||
)
|
||||
|
||||
type (
|
||||
Adler32 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
)
|
||||
|
||||
func (m *Adler32) String() string {
|
||||
return "adler32"
|
||||
}
|
||||
|
||||
func (m *Adler32) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = adler32.New()
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Adler32) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = adler32.New()
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
57
checksum/adler32_test.go
Normal file
57
checksum/adler32_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/adler32"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAdler32_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Adler32)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
adler32.New().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Adler32) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
adler32sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Adler32{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func adler32sum(b []byte) []byte {
|
||||
h := adler32.New()
|
||||
h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestAdler32_String(t *testing.T) {
|
||||
assert.Equals(t, (&Adler32{}).String(), "adler32")
|
||||
}
|
134
checksum/crc.go
Normal file
134
checksum/crc.go
Normal file
@ -0,0 +1,134 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"hash/crc64"
|
||||
)
|
||||
|
||||
var (
|
||||
IEEETable = crc32.IEEETable
|
||||
CastagnoliTable = crc32.MakeTable(crc32.Castagnoli)
|
||||
KoopmanTable = crc32.MakeTable(crc32.Koopman)
|
||||
|
||||
ISOTable = crc64.MakeTable(crc64.ISO)
|
||||
ECMATable = crc64.MakeTable(crc64.ECMA)
|
||||
)
|
||||
|
||||
type (
|
||||
Crc32Ieee struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Crc32Castagnoli struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Crc32Koopman struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Crc64Iso struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Crc64Ecma struct {
|
||||
d hash.Hash
|
||||
}
|
||||
)
|
||||
|
||||
func (m *Crc32Ieee) String() string {
|
||||
return "crc32ieee"
|
||||
}
|
||||
|
||||
func (m *Crc32Ieee) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = crc32.New(IEEETable)
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Crc32Ieee) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = crc32.New(IEEETable)
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Crc32Castagnoli) String() string {
|
||||
return "crc32castagnoli"
|
||||
}
|
||||
|
||||
func (m *Crc32Castagnoli) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = crc32.New(CastagnoliTable)
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Crc32Castagnoli) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = crc32.New(CastagnoliTable)
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Crc32Koopman) String() string {
|
||||
return "crc32koopman"
|
||||
}
|
||||
|
||||
func (m *Crc32Koopman) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = crc32.New(KoopmanTable)
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Crc32Koopman) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = crc32.New(KoopmanTable)
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Crc64Iso) String() string {
|
||||
return "crc64iso"
|
||||
}
|
||||
|
||||
func (m *Crc64Iso) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = crc64.New(ISOTable)
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Crc64Iso) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = crc64.New(ISOTable)
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Crc64Ecma) String() string {
|
||||
return "crc64ecma"
|
||||
}
|
||||
|
||||
func (m *Crc64Ecma) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = crc64.New(ECMATable)
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Crc64Ecma) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = crc64.New(ECMATable)
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
57
checksum/crc32castagnoli_test.go
Normal file
57
checksum/crc32castagnoli_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCrc32Castagnoli_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Crc32Castagnoli)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
crc32.New(CastagnoliTable).Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Crc32Castagnoli) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
crc32CastagnoliSum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Crc32Castagnoli{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func crc32CastagnoliSum(b []byte) []byte {
|
||||
h := crc32.New(CastagnoliTable)
|
||||
h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestCrc32Castagnoli_String(t *testing.T) {
|
||||
assert.Equals(t, (&Crc32Castagnoli{}).String(), "crc32castagnoli")
|
||||
}
|
57
checksum/crc32ieee_test.go
Normal file
57
checksum/crc32ieee_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCrc32Ieee_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Crc32Ieee)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
crc32.New(IEEETable).Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Crc32Ieee) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
crc32Ieeesum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Crc32Ieee{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func crc32Ieeesum(b []byte) []byte {
|
||||
h := crc32.New(crc32.IEEETable)
|
||||
h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestCrc32Ieee_String(t *testing.T) {
|
||||
assert.Equals(t, (&Crc32Ieee{}).String(), "crc32ieee")
|
||||
}
|
57
checksum/crc32koopman_test.go
Normal file
57
checksum/crc32koopman_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCrc32Koopman_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Crc32Koopman)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
crc32.New(KoopmanTable).Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Crc32Koopman) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
crc32KoopmanSum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Crc32Koopman{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func crc32KoopmanSum(b []byte) []byte {
|
||||
h := crc32.New(KoopmanTable)
|
||||
h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestCrc32Koopman_String(t *testing.T) {
|
||||
assert.Equals(t, (&Crc32Koopman{}).String(), "crc32koopman")
|
||||
}
|
57
checksum/crc64ecma_test.go
Normal file
57
checksum/crc64ecma_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/crc64"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCrc64Ecma_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Crc64Ecma)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
crc64.New(ECMATable).Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Crc64Ecma) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
crc64EcmaSum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Crc64Ecma{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func crc64EcmaSum(b []byte) []byte {
|
||||
h := crc64.New(ECMATable)
|
||||
h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestCrc64Ecma_String(t *testing.T) {
|
||||
assert.Equals(t, (&Crc64Ecma{}).String(), "crc64ecma")
|
||||
}
|
57
checksum/crc64iso_test.go
Normal file
57
checksum/crc64iso_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/crc64"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCrc64Iso_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Crc64Iso)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
crc64.New(ISOTable).Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Crc64Iso) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
crc64IsoSum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Crc64Iso{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func crc64IsoSum(b []byte) []byte {
|
||||
h := crc64.New(ISOTable)
|
||||
h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestCrc64Iso_String(t *testing.T) {
|
||||
assert.Equals(t, (&Crc64Iso{}).String(), "crc64iso")
|
||||
}
|
28
checksum/crc_test.go
Normal file
28
checksum/crc_test.go
Normal file
@ -0,0 +1,28 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash/crc32"
|
||||
"hash/crc64"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIEEETable(t *testing.T) {
|
||||
assert.Equals(t, IEEETable, crc32.IEEETable)
|
||||
}
|
||||
|
||||
func TestCastagnoliTable(t *testing.T) {
|
||||
assert.Equals(t, CastagnoliTable, crc32.MakeTable(crc32.Castagnoli))
|
||||
}
|
||||
|
||||
func TestKoopmanTable(t *testing.T) {
|
||||
assert.Equals(t, KoopmanTable, crc32.MakeTable(crc32.Koopman))
|
||||
}
|
||||
|
||||
func TestISOTable(t *testing.T) {
|
||||
assert.Equals(t, ISOTable, crc64.MakeTable(crc64.ISO))
|
||||
}
|
||||
|
||||
func TestECMATable(t *testing.T) {
|
||||
assert.Equals(t, ECMATable, crc64.MakeTable(crc64.ECMA))
|
||||
}
|
11
checksum/def.go
Normal file
11
checksum/def.go
Normal file
@ -0,0 +1,11 @@
|
||||
package checksum
|
||||
|
||||
import "fmt"
|
||||
|
||||
type (
|
||||
Func interface {
|
||||
fmt.Stringer
|
||||
Append(data []byte)
|
||||
Finish() []byte
|
||||
}
|
||||
)
|
57
checksum/fnc128_test.go
Normal file
57
checksum/fnc128_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFnv128_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Fnv128)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
fnv.New128().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Fnv128) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
fnv128Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Fnv128{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func fnv128Sum(b []byte) []byte {
|
||||
h := fnv.New128()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestFnv128_String(t *testing.T) {
|
||||
assert.Equals(t, (&Fnv128{}).String(), "fnv128")
|
||||
}
|
57
checksum/fnc128a_test.go
Normal file
57
checksum/fnc128a_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFnv128a_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Fnv128a)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
fnv.New128a().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Fnv128a) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
fnv128aSum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Fnv128a{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func fnv128aSum(b []byte) []byte {
|
||||
h := fnv.New128a()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestFnv128a_String(t *testing.T) {
|
||||
assert.Equals(t, (&Fnv128a{}).String(), "fnv128a")
|
||||
}
|
57
checksum/fnc32_test.go
Normal file
57
checksum/fnc32_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFnv32_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Fnv32)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
fnv.New32().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Fnv32) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
fnv32Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Fnv32{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func fnv32Sum(b []byte) []byte {
|
||||
h := fnv.New32()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestFnv32_String(t *testing.T) {
|
||||
assert.Equals(t, (&Fnv32{}).String(), "fnv32")
|
||||
}
|
57
checksum/fnc32a_test.go
Normal file
57
checksum/fnc32a_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFnv32a_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Fnv32a)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
fnv.New32a().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Fnv32a) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
fnv32aSum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Fnv32a{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func fnv32aSum(b []byte) []byte {
|
||||
h := fnv.New32a()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestFnv32a_String(t *testing.T) {
|
||||
assert.Equals(t, (&Fnv32a{}).String(), "fnv32a")
|
||||
}
|
57
checksum/fnc64_test.go
Normal file
57
checksum/fnc64_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFnv64_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Fnv64)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
fnv.New64().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Fnv64) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
fnv64Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Fnv64{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func fnv64Sum(b []byte) []byte {
|
||||
h := fnv.New64()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestFnv64_String(t *testing.T) {
|
||||
assert.Equals(t, (&Fnv64{}).String(), "fnv64")
|
||||
}
|
57
checksum/fnc64a_test.go
Normal file
57
checksum/fnc64a_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFnv64a_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Fnv64a)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
fnv.New64a().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Fnv64a) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
fnv64aSum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Fnv64a{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func fnv64aSum(b []byte) []byte {
|
||||
h := fnv.New64a()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestFnv64a_String(t *testing.T) {
|
||||
assert.Equals(t, (&Fnv64a{}).String(), "fnv64a")
|
||||
}
|
147
checksum/fnv.go
Normal file
147
checksum/fnv.go
Normal file
@ -0,0 +1,147 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
)
|
||||
|
||||
type (
|
||||
Fnv32 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Fnv32a struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Fnv64 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Fnv64a struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Fnv128 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Fnv128a struct {
|
||||
d hash.Hash
|
||||
}
|
||||
)
|
||||
|
||||
func (m *Fnv32) String() string {
|
||||
return "fnv32"
|
||||
}
|
||||
|
||||
func (m *Fnv32) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New32()
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Fnv32) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New32()
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Fnv32a) String() string {
|
||||
return "fnv32a"
|
||||
}
|
||||
|
||||
func (m *Fnv32a) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New32a()
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Fnv32a) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New32a()
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Fnv64) String() string {
|
||||
return "fnv64"
|
||||
}
|
||||
|
||||
func (m *Fnv64) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New64()
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Fnv64) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New64()
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Fnv64a) String() string {
|
||||
return "fnv64a"
|
||||
}
|
||||
|
||||
func (m *Fnv64a) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New64a()
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Fnv64a) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New64a()
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Fnv128) String() string {
|
||||
return "fnv128"
|
||||
}
|
||||
|
||||
func (m *Fnv128) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New128()
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Fnv128) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New128()
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (m *Fnv128a) String() string {
|
||||
return "fnv128a"
|
||||
}
|
||||
|
||||
func (m *Fnv128a) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New128a()
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Fnv128a) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = fnv.New128a()
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
32
checksum/md5.go
Normal file
32
checksum/md5.go
Normal file
@ -0,0 +1,32 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"hash"
|
||||
)
|
||||
|
||||
type (
|
||||
Md5 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
)
|
||||
|
||||
func (m *Md5) String() string {
|
||||
return "md5"
|
||||
}
|
||||
|
||||
func (m *Md5) Append(data []byte) {
|
||||
if m.d == nil {
|
||||
m.d = md5.New()
|
||||
}
|
||||
|
||||
m.d.Write(data)
|
||||
}
|
||||
|
||||
func (m *Md5) Finish() []byte {
|
||||
if m.d == nil {
|
||||
m.d = md5.New()
|
||||
}
|
||||
|
||||
return m.d.Sum(nil)
|
||||
}
|
57
checksum/md5_test.go
Normal file
57
checksum/md5_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMd5_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Md5)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
md5.New().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Md5) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
md5sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Md5{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func md5sum(b []byte) []byte {
|
||||
h := md5.New()
|
||||
h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestMd5_String(t *testing.T) {
|
||||
assert.Equals(t, (&Md5{}).String(), "md5")
|
||||
}
|
80
checksum/murmur3.go
Normal file
80
checksum/murmur3.go
Normal file
@ -0,0 +1,80 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/spaolacci/murmur3"
|
||||
"hash"
|
||||
|
||||
_ "github.com/spaolacci/murmur3"
|
||||
)
|
||||
|
||||
type (
|
||||
Murmur332 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Murmur364 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
Murmur3128 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
)
|
||||
|
||||
func (s *Murmur332) String() string {
|
||||
return "murmur3 32"
|
||||
}
|
||||
|
||||
func (s *Murmur332) Append(data []byte) {
|
||||
if s.d == nil {
|
||||
s.d = murmur3.New32()
|
||||
}
|
||||
|
||||
s.d.Write(data)
|
||||
}
|
||||
|
||||
func (s *Murmur332) Finish() []byte {
|
||||
if s.d == nil {
|
||||
s.d = murmur3.New32()
|
||||
}
|
||||
|
||||
return s.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (s *Murmur364) String() string {
|
||||
return "murmur3 64"
|
||||
}
|
||||
|
||||
func (s *Murmur364) Append(data []byte) {
|
||||
if s.d == nil {
|
||||
s.d = murmur3.New64()
|
||||
}
|
||||
|
||||
s.d.Write(data)
|
||||
}
|
||||
|
||||
func (s *Murmur364) Finish() []byte {
|
||||
if s.d == nil {
|
||||
s.d = murmur3.New64()
|
||||
}
|
||||
|
||||
return s.d.Sum(nil)
|
||||
}
|
||||
|
||||
func (s *Murmur3128) String() string {
|
||||
return "murmur3 128"
|
||||
}
|
||||
|
||||
func (s *Murmur3128) Append(data []byte) {
|
||||
if s.d == nil {
|
||||
s.d = murmur3.New128()
|
||||
}
|
||||
|
||||
s.d.Write(data)
|
||||
}
|
||||
|
||||
func (s *Murmur3128) Finish() []byte {
|
||||
if s.d == nil {
|
||||
s.d = murmur3.New128()
|
||||
}
|
||||
|
||||
return s.d.Sum(nil)
|
||||
}
|
57
checksum/murmur3_128_test.go
Normal file
57
checksum/murmur3_128_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/spaolacci/murmur3"
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMurmur3128_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Murmur3128)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
murmur3.New128().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Murmur3128) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
murmur3128Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Murmur3128{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func murmur3128Sum(b []byte) []byte {
|
||||
h := murmur3.New128()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestMurmur3128_String(t *testing.T) {
|
||||
assert.Equals(t, (&Murmur3128{}).String(), "murmur3 128")
|
||||
}
|
57
checksum/murmur3_32_test.go
Normal file
57
checksum/murmur3_32_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/spaolacci/murmur3"
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMurmur332_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Murmur332)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
murmur3.New32().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Murmur332) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
murmur332Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Murmur332{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func murmur332Sum(b []byte) []byte {
|
||||
h := murmur3.New32()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestMurmur332_String(t *testing.T) {
|
||||
assert.Equals(t, (&Murmur332{}).String(), "murmur3 32")
|
||||
}
|
57
checksum/murmur3_64_test.go
Normal file
57
checksum/murmur3_64_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"github.com/spaolacci/murmur3"
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMurmur364_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Murmur364)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
murmur3.New64().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Murmur364) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
murmur364Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Murmur364{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func murmur364Sum(b []byte) []byte {
|
||||
h := murmur3.New64()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestMurmur364_String(t *testing.T) {
|
||||
assert.Equals(t, (&Murmur364{}).String(), "murmur3 64")
|
||||
}
|
32
checksum/sha1.go
Normal file
32
checksum/sha1.go
Normal file
@ -0,0 +1,32 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"hash"
|
||||
)
|
||||
|
||||
type (
|
||||
Sha1 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
)
|
||||
|
||||
func (s *Sha1) String() string {
|
||||
return "sha1"
|
||||
}
|
||||
|
||||
func (s *Sha1) Append(data []byte) {
|
||||
if s.d == nil {
|
||||
s.d = sha1.New()
|
||||
}
|
||||
|
||||
s.d.Write(data)
|
||||
}
|
||||
|
||||
func (s *Sha1) Finish() []byte {
|
||||
if s.d == nil {
|
||||
s.d = sha1.New()
|
||||
}
|
||||
|
||||
return s.d.Sum(nil)
|
||||
}
|
57
checksum/sha1_test.go
Normal file
57
checksum/sha1_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSha1_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Sha1)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
sha1.New().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Sha1) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
sha1Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Sha1{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func sha1Sum(b []byte) []byte {
|
||||
h := sha1.New()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestSha1_String(t *testing.T) {
|
||||
assert.Equals(t, (&Sha1{}).String(), "sha1")
|
||||
}
|
32
checksum/sha256.go
Normal file
32
checksum/sha256.go
Normal file
@ -0,0 +1,32 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"hash"
|
||||
)
|
||||
|
||||
type (
|
||||
Sha256 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
)
|
||||
|
||||
func (s *Sha256) String() string {
|
||||
return "sha256"
|
||||
}
|
||||
|
||||
func (s *Sha256) Append(data []byte) {
|
||||
if s.d == nil {
|
||||
s.d = sha256.New()
|
||||
}
|
||||
|
||||
s.d.Write(data)
|
||||
}
|
||||
|
||||
func (s *Sha256) Finish() []byte {
|
||||
if s.d == nil {
|
||||
s.d = sha256.New()
|
||||
}
|
||||
|
||||
return s.d.Sum(nil)
|
||||
}
|
57
checksum/sha256_test.go
Normal file
57
checksum/sha256_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSha256_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Sha256)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
sha256.New().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Sha256) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
sha256Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Sha256{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func sha256Sum(b []byte) []byte {
|
||||
h := sha256.New()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestSha256_String(t *testing.T) {
|
||||
assert.Equals(t, (&Sha256{}).String(), "sha256")
|
||||
}
|
32
checksum/sha512.go
Normal file
32
checksum/sha512.go
Normal file
@ -0,0 +1,32 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"crypto/sha512"
|
||||
"hash"
|
||||
)
|
||||
|
||||
type (
|
||||
Sha512 struct {
|
||||
d hash.Hash
|
||||
}
|
||||
)
|
||||
|
||||
func (s *Sha512) String() string {
|
||||
return "sha512"
|
||||
}
|
||||
|
||||
func (s *Sha512) Append(data []byte) {
|
||||
if s.d == nil {
|
||||
s.d = sha512.New()
|
||||
}
|
||||
|
||||
s.d.Write(data)
|
||||
}
|
||||
|
||||
func (s *Sha512) Finish() []byte {
|
||||
if s.d == nil {
|
||||
s.d = sha512.New()
|
||||
}
|
||||
|
||||
return s.d.Sum(nil)
|
||||
}
|
57
checksum/sha512_test.go
Normal file
57
checksum/sha512_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package checksum
|
||||
|
||||
import (
|
||||
"crypto/sha512"
|
||||
"github.com/tursom/checksum/assert"
|
||||
"hash"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSha512_Finish(t *testing.T) {
|
||||
type fields struct {
|
||||
d hash.Hash
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
builder func(m *Sha512)
|
||||
want []byte
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
fields{},
|
||||
nil,
|
||||
sha512.New().Sum(nil),
|
||||
},
|
||||
{
|
||||
"hello",
|
||||
fields{},
|
||||
func(m *Sha512) {
|
||||
m.Append([]byte("hello"))
|
||||
},
|
||||
sha512Sum([]byte("hello")),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
m := &Sha512{
|
||||
d: tt.fields.d,
|
||||
}
|
||||
if tt.builder != nil {
|
||||
tt.builder(m)
|
||||
}
|
||||
|
||||
assert.Equals(t, m.Finish(), tt.want)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func sha512Sum(b []byte) []byte {
|
||||
h := sha512.New()
|
||||
_, _ = h.Write(b)
|
||||
return h.Sum(nil)
|
||||
}
|
||||
|
||||
func TestSha512_String(t *testing.T) {
|
||||
assert.Equals(t, (&Sha512{}).String(), "sha512")
|
||||
}
|
109
cmd/checksum/main.go
Normal file
109
cmd/checksum/main.go
Normal file
@ -0,0 +1,109 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/tursom/checksum/checksum"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
hashFuncs = []func() checksum.Func{
|
||||
func() checksum.Func { return &checksum.Md5{} },
|
||||
func() checksum.Func { return &checksum.Sha1{} },
|
||||
func() checksum.Func { return &checksum.Sha256{} },
|
||||
func() checksum.Func { return &checksum.Sha512{} },
|
||||
func() checksum.Func { return &checksum.Murmur332{} },
|
||||
func() checksum.Func { return &checksum.Murmur364{} },
|
||||
func() checksum.Func { return &checksum.Murmur3128{} },
|
||||
func() checksum.Func { return &checksum.Adler32{} },
|
||||
func() checksum.Func { return &checksum.Crc32Ieee{} },
|
||||
func() checksum.Func { return &checksum.Crc32Castagnoli{} },
|
||||
func() checksum.Func { return &checksum.Crc32Koopman{} },
|
||||
func() checksum.Func { return &checksum.Crc64Iso{} },
|
||||
func() checksum.Func { return &checksum.Crc64Ecma{} },
|
||||
func() checksum.Func { return &checksum.Fnv32{} },
|
||||
func() checksum.Func { return &checksum.Fnv32a{} },
|
||||
func() checksum.Func { return &checksum.Fnv64{} },
|
||||
func() checksum.Func { return &checksum.Fnv64a{} },
|
||||
func() checksum.Func { return &checksum.Fnv128{} },
|
||||
func() checksum.Func { return &checksum.Fnv128a{} },
|
||||
}
|
||||
)
|
||||
|
||||
func main() {
|
||||
path, checksumType := readConfig()
|
||||
doCheck(path, hashFuncs[checksumType-1])
|
||||
waitExit()
|
||||
}
|
||||
|
||||
func readConfig() (string, uint) {
|
||||
fmt.Println("Please select checksum path:")
|
||||
fmt.Print(">>> ")
|
||||
var path string
|
||||
if _, err := fmt.Scanln(&path); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Please select checksum type:")
|
||||
for i, f := range hashFuncs {
|
||||
fmt.Printf("%d. %s\n", i+1, f().String())
|
||||
}
|
||||
fmt.Print(">>> ")
|
||||
var checksumType uint
|
||||
if _, err := fmt.Scanln(&checksumType); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return path, checksumType
|
||||
}
|
||||
|
||||
func doCheck(path string, factory func() checksum.Func) {
|
||||
checkFile(path, factory)
|
||||
}
|
||||
|
||||
func checkFile(path string, factory func() checksum.Func) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
fileStat, err := file.Stat()
|
||||
if err != nil {
|
||||
panic(errors.New(fmt.Sprintf("failed to check status: %s", err)))
|
||||
}
|
||||
|
||||
switch mode := fileStat.Mode(); {
|
||||
case mode.IsDir():
|
||||
filepath.Walk(file.Name(), func(subPath string, info fs.FileInfo, err error) error {
|
||||
if subPath == path {
|
||||
return nil
|
||||
}
|
||||
checkFile(subPath, factory)
|
||||
return nil
|
||||
})
|
||||
case mode.IsRegular():
|
||||
f := factory()
|
||||
|
||||
buffer := make([]byte, 1024)
|
||||
for {
|
||||
n, err := file.Read(buffer)
|
||||
if n == 0 || err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f.Append(buffer[0:n])
|
||||
}
|
||||
|
||||
fmt.Printf("file: %s\nchecksum: %x\n\n", path, f.Finish())
|
||||
}
|
||||
}
|
||||
|
||||
func waitExit() {
|
||||
fmt.Println("Press enter to exit.")
|
||||
_, _ = fmt.Scanln()
|
||||
}
|
Loading…
Reference in New Issue
Block a user