init commit

This commit is contained in:
tursom 2023-08-01 15:32:05 +08:00
commit 1cbaf88b29
37 changed files with 1992 additions and 0 deletions

181
.gitignore vendored Normal file
View 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
View 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>

View 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>

View 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
View 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
View 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
View 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
View 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
View 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)
}

View 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")
}

View 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")
}

View 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")
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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)
}

View 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")
}

View 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")
}

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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()
}

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module github.com/tursom/checksum
go 1.20
require github.com/spaolacci/murmur3 v1.1.0