Compare commits

...

16 Commits

Author SHA1 Message Date
dependabot[bot]
cbfd4b83b4
Bump golang.org/x/crypto from 0.22.0 to 0.24.0 (#32)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-05 12:50:57 -07:00
dependabot[bot]
67f76830a4
Bump golang.org/x/crypto from 0.21.0 to 0.22.0 (#30)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-06 00:12:08 -07:00
dependabot[bot]
ba45bee638
Bump golang.org/x/crypto from 0.20.0 to 0.21.0 (#29)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-08 21:11:07 -08:00
dependabot[bot]
c76c7965e9
Bump golang.org/x/crypto from 0.19.0 to 0.20.0 (#28)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-29 23:42:32 -08:00
dependabot[bot]
37488a3804
Bump golang.org/x/crypto from 0.18.0 to 0.19.0 (#27)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-09 14:13:19 -08:00
5f109b6caf
Feat[hash]: Add crc64 with 2 polynomial options 2024-01-28 22:44:23 -08:00
dependabot[bot]
44e5d2d424
Bump golang.org/x/crypto from 0.17.0 to 0.18.0 (#26)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.17.0 to 0.18.0.
- [Commits](https://github.com/golang/crypto/compare/v0.17.0...v0.18.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-09 14:01:04 -08:00
dependabot[bot]
ec984c1a8a
Bump actions/setup-go from 4 to 5 (#23)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-30 13:48:35 -08:00
dependabot[bot]
5e01e28a17
Bump golang.org/x/crypto from 0.16.0 to 0.17.0 (#25)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.16.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-26 16:44:35 -08:00
dependabot[bot]
3aff8ba749
Bump github/codeql-action from 2 to 3 (#24)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-15 15:38:37 -08:00
dependabot[bot]
40fe053b45
Bump golang.org/x/crypto from 0.15.0 to 0.16.0 (#22)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.15.0 to 0.16.0.
- [Commits](https://github.com/golang/crypto/compare/v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-01 20:01:58 -08:00
4e59e82d82
Fix[hash]: Fix benchmarking 2023-11-14 14:37:35 -08:00
22bad87f21
Feat/Refactor[hash]: !!BREAKING!! add CRC32 and general refactor !!BREAKING!! (#21) 2023-11-14 14:31:35 -08:00
9ecc1d1677
Fix[entropy]: Fix typo in docs and benchmark code 2023-11-13 04:59:39 -08:00
dependabot[bot]
b4aea38e0b
Bump golang.org/x/crypto from 0.14.0 to 0.15.0 (#20)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.15.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-09 09:00:16 -08:00
90e435641d
Feat[pool]: Add new interfaces for compatibility (#19) 2023-10-29 20:20:46 -07:00
11 changed files with 282 additions and 163 deletions

@ -42,7 +42,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -53,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@ -67,4 +67,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3

@ -9,7 +9,7 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: '1.18'
- name: Run coverage

@ -2,67 +2,12 @@ package common
import (
"errors"
"fmt"
"io"
"os"
"sync"
"testing"
"git.tcp.direct/kayos/common/entropy"
"git.tcp.direct/kayos/common/hash"
"git.tcp.direct/kayos/common/squish"
)
var needle = []byte(entropy.RandStr(16))
func TestBlakeEqualAndB64(t *testing.T) {
var clone = make([]byte, len(needle))
copy(clone, needle)
if !hash.BlakeEqual(needle, clone) {
t.Fatalf("BlakeEqual failed! Values %v and %v should have been equal.\n|---->Lengths: %d and %d",
needle, clone, len(needle), len(clone),
)
}
falseclone := []byte(entropy.RandStr(16))
if hash.BlakeEqual(needle, falseclone) {
t.Fatalf("BlakeEqual failed! Values %v and %v should NOT have been equal.\n|---->Lengths: %d and %d",
needle, clone, len(needle), len(clone),
)
}
var based = [2][]byte{needle, clone}
based[0] = []byte(squish.B64e(based[0]))
based[1] = []byte(squish.B64e(based[0]))
if hash.BlakeEqual(based[0], based[1]) {
t.Fatalf("Base64 encoding failed! Values %v and %v should NOT have been equal.\n|---->Lengths: %d and %d",
based[0], based[1], len(based[0]), len(based[1]),
)
}
// sneakin in some code coverage rq dwai nbd
bogusRd, bogusWrt := io.Pipe()
bogusRd2, bogusWrt2 := io.Pipe()
t.Logf("\n")
go func() {
Fprint(io.MultiWriter(bogusWrt, os.Stdout), fmt.Sprintf("[PASS] based[0] = %s", string(based[0])))
Fprintf(io.MultiWriter(bogusWrt2, os.Stdout), "\n[PASS] based[1] = %s", string(based[0]))
}()
_ = bogusWrt.CloseWithError(io.ErrClosedPipe)
_ = bogusWrt2.CloseWithError(io.ErrClosedPipe)
_, err := bogusRd.Read([]byte{})
if err == nil {
t.Fatalf("should have been an error...")
}
_, err = bogusRd2.Read([]byte{})
if err == nil {
t.Fatalf("should have been an error...")
}
}
func TestAbs(t *testing.T) {
var start = int32(entropy.RNG(5))
for start < 1 {

@ -152,7 +152,7 @@ randStr is an overoptimized (read: dummy fast) random string generator.
at 55,555 characters, we are at:
~57,000 bytes per op with string builders
~57,000 bytes per op with byte builders
vs
~210,000 bytes per op with string builders.

@ -168,13 +168,13 @@ func Test_RNGUint32(t *testing.T) {
func Benchmark_RandStr(b *testing.B) {
toTest := []int{5, 25, 55, 500, 55555}
for n := range toTest {
for _, ln := range toTest {
for i := 1; i != 5; i++ {
b.Run(fmt.Sprintf("lenSeries%d/run%d", n, i), func(b *testing.B) {
b.Run(fmt.Sprintf("len%d/run%d", ln, i), func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for tn := 0; tn != b.N; tn++ {
RandStr(n)
RandStr(ln)
}
})
}

4
go.mod

@ -3,11 +3,11 @@ module git.tcp.direct/kayos/common
go 1.19
require (
golang.org/x/crypto v0.14.0
golang.org/x/crypto v0.24.0
nullprogram.com/x/rng v1.1.0
)
require golang.org/x/sys v0.13.0 // indirect
require golang.org/x/sys v0.21.0 // indirect
retract (
v0.9.1 // premature (race condition)

8
go.sum

@ -1,6 +1,6 @@
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
nullprogram.com/x/rng v1.1.0 h1:SMU7DHaQSWtKJNTpNFIFt8Wd/KSmOuSDPXrMFp/UMro=
nullprogram.com/x/rng v1.1.0/go.mod h1:glGw6V87vyfawxCzqOABL3WfL95G65az9Z2JZCylCkg=

@ -1,7 +1,6 @@
package hash
import (
"bytes"
"crypto/md5" //nolint:gosec
"crypto/sha1" //nolint:gosec
"crypto/sha256"
@ -9,6 +8,8 @@ import (
"errors"
"fmt"
"hash"
"hash/crc32"
"hash/crc64"
"io"
"os"
"sync"
@ -25,8 +26,41 @@ const (
TypeSHA256
TypeSHA512
TypeMD5
TypeCRC32
TypeCRC64ISO
TypeCRC64ECMA
)
var typeToString = map[Type]string{
TypeNull: "null", TypeBlake2b: "blake2b", TypeSHA1: "sha1",
TypeSHA256: "sha256", TypeSHA512: "sha512",
TypeMD5: "md5", TypeCRC32: "crc32",
TypeCRC64ISO: "crc64-iso", TypeCRC64ECMA: "crc64-ecma",
}
var stringToType = map[string]Type{
"null": TypeNull, "blake2b": TypeBlake2b, "sha1": TypeSHA1,
"sha256": TypeSHA256, "sha512": TypeSHA512,
"md5": TypeMD5, "crc32": TypeCRC32,
"crc64-iso": TypeCRC64ISO, "crc64-ecma": TypeCRC64ECMA,
}
func StringToType(s string) Type {
t, ok := stringToType[s]
if !ok {
return TypeNull
}
return t
}
func (t Type) String() string {
s, ok := typeToString[t]
if !ok {
return "unknown"
}
return s
}
var (
sha1Pool = &sync.Pool{
New: func() interface{} {
@ -54,6 +88,24 @@ var (
return h
},
}
crc32Pool = &sync.Pool{
New: func() interface{} {
return crc32.NewIEEE()
},
}
crc64ISOPool = &sync.Pool{
New: func() interface{} {
// ISO and ECMA are pre-computed in the stdlib, so Make is just fetching them, not computing them.
h := crc64.New(crc64.MakeTable(crc64.ISO))
return h
},
}
crc64ECMAPool = &sync.Pool{
New: func() interface{} {
h := crc64.New(crc64.MakeTable(crc64.ECMA))
return h
},
}
)
func Sum(ht Type, b []byte) []byte {
@ -74,6 +126,16 @@ func Sum(ht Type, b []byte) []byte {
case TypeMD5:
h = md5Pool.Get().(hash.Hash)
defer md5Pool.Put(h)
case TypeCRC32:
h = crc32Pool.Get().(hash.Hash)
defer crc32Pool.Put(h)
case TypeCRC64ISO:
h = crc64ISOPool.Get().(hash.Hash)
defer crc64ISOPool.Put(h)
case TypeCRC64ECMA:
h = crc64ECMAPool.Get().(hash.Hash)
defer crc64ECMAPool.Put(h)
default:
return nil
}
@ -83,13 +145,8 @@ func Sum(ht Type, b []byte) []byte {
return sum
}
// Blake2bSum ignores all errors and gives you a blakae2b 64 hash value as a byte slice. (or panics somehow)
func Blake2bSum(b []byte) []byte {
return Sum(TypeBlake2b, b)
}
// BlakeFileChecksum will attempt to calculate a blake2b checksum of the given file path's contents.
func BlakeFileChecksum(path string) (buf []byte, err error) {
// SumFile will attempt to calculate a blake2b checksum of the given file path's contents.
func SumFile(ht Type, path string) (buf []byte, err error) {
var f *os.File
f, err = os.Open(path)
if err != nil {
@ -107,10 +164,5 @@ func BlakeFileChecksum(path string) (buf []byte, err error) {
return nil, errors.New("file is empty")
}
return Sum(TypeBlake2b, buf), nil
}
// BlakeEqual will take in two byte slices, hash them with blake2b, and tell you if the resulting checksums match.
func BlakeEqual(a []byte, b []byte) bool {
return bytes.Equal(Blake2bSum(a), Blake2bSum(b))
return Sum(ht, buf), nil
}

@ -4,101 +4,136 @@ import (
"bytes"
"encoding/base64"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"git.tcp.direct/kayos/common/entropy"
"git.tcp.direct/kayos/common/squish"
)
const (
kayosBlake2b = "Kr+6ONDx+cq/WvhHpQE/4LVuJYi9QHz1TztHNTWwa9KJWqHxfTNLKF3YxrcLptA3wO0KHm83Lq7gpBWgCQzPag=="
kayosMD5 = "aoNjwileNitB208vOwpIow=="
kayosSHA1 = "M23ElC0sQYAK+MaMZVmza2L8mss="
kayosSHA256 = "BagY0TmoGR3O7t80BGm4K6UHPlqEg6HJirwQmhrPK4U="
kayosSHA512 = "xiuo2na76acrWXCTTR++O1pPZabOhyj8nbfb5Go3e1pEq9VJYIsOioTXalf2GCuERmFecWkmaL5QI8mIXXWpNA=="
kayosBlake2b = "Kr+6ONDx+cq/WvhHpQE/4LVuJYi9QHz1TztHNTWwa9KJWqHxfTNLKF3YxrcLptA3wO0KHm83Lq7gpBWgCQzPag=="
kayosMD5 = "aoNjwileNitB208vOwpIow=="
kayosSHA1 = "M23ElC0sQYAK+MaMZVmza2L8mss="
kayosSHA256 = "BagY0TmoGR3O7t80BGm4K6UHPlqEg6HJirwQmhrPK4U="
kayosSHA512 = "xiuo2na76acrWXCTTR++O1pPZabOhyj8nbfb5Go3e1pEq9VJYIsOioTXalf2GCuERmFecWkmaL5QI8mIXXWpNA=="
kayosCRC32 = "xtig5w=="
kayosCRC64ISO = "YVx8IpQawAA="
kayosCRC64ECMA = "Nn5+vneo4j4="
)
func TestBlake2bsum(t *testing.T) {
og := squish.B64d(kayosBlake2b)
newc := Blake2bSum([]byte("kayos\n"))
if !bytes.Equal(newc, og) {
t.Fatalf("wanted: %v, got %v", kayosBlake2b, squish.B64e(newc))
}
if !BlakeEqual([]byte("kayos\n"), []byte{107, 97, 121, 111, 115, 10}) {
t.Fatalf("BlakeEqual should have been true. %s should == %s", []byte("kayos\n"), []byte{107, 97, 121, 111, 115, 92, 110})
}
t.Logf("[blake2bSum] success: %s", kayosBlake2b)
}
var kayosByteSlice = []byte{107, 97, 121, 111, 115, 10}
func TestBlakeFileChecksum(t *testing.T) {
path := t.TempDir() + "/blake2b.dat"
err := os.WriteFile(path, []byte{107, 97, 121, 111, 115, 10}, os.ModePerm)
if err != nil {
t.Errorf("[FAIL] failed to write test fle for TestBlakeFileChecksum: %s", err.Error())
var (
ogsha1, _ = base64.StdEncoding.DecodeString(kayosSHA1)
ogsha256, _ = base64.StdEncoding.DecodeString(kayosSHA256)
ogsha512, _ = base64.StdEncoding.DecodeString(kayosSHA512)
ogmd5, _ = base64.StdEncoding.DecodeString(kayosMD5)
ogBlake2b, _ = base64.StdEncoding.DecodeString(kayosBlake2b)
ogCRC32, _ = base64.StdEncoding.DecodeString(kayosCRC32)
ogCRC64ISO, _ = base64.StdEncoding.DecodeString(kayosCRC64ISO)
ogCRC64ECMA, _ = base64.StdEncoding.DecodeString(kayosCRC64ECMA)
valids = map[Type][]byte{
TypeSHA1: ogsha1,
TypeSHA256: ogsha256,
TypeSHA512: ogsha512,
TypeMD5: ogmd5,
TypeCRC32: ogCRC32,
TypeCRC64ISO: ogCRC64ISO,
TypeCRC64ECMA: ogCRC64ECMA,
TypeBlake2b: ogBlake2b,
}
filecheck, err2 := BlakeFileChecksum(path)
if err2 != nil {
t.Errorf("[FAIL] failed to read test fle for TestBlakeFileChecksum: %s", err2.Error())
}
if len(filecheck) == 0 {
t.Errorf("[FAIL] got nil output from BlakeFileChecksum")
}
if !bytes.Equal(filecheck, squish.B64d(kayosBlake2b)) {
t.Fatalf("[FAIL] wanted: %v, got %v", kayosBlake2b, squish.B64e(filecheck))
}
badfile, err3 := BlakeFileChecksum(t.TempDir() + "/" + entropy.RandStr(50))
if err3 == nil {
t.Errorf("[FAIL] shouldn't have been able to read phony file")
}
if len(badfile) != 0 {
t.Errorf("[FAIL] got non-nil output from bogus file: %v", badfile)
}
if !bytes.Equal(filecheck, squish.B64d(kayosBlake2b)) {
t.Fatalf("[FAIL] wanted: %v, got %v", kayosBlake2b, squish.B64e(filecheck))
}
err = os.WriteFile(path+".empty", []byte{}, os.ModePerm)
if err != nil {
t.Errorf("[FAIL] failed to write test fle for TestBlakeFileChecksum: %s", err.Error())
}
_, err4 := BlakeFileChecksum(path + ".empty")
if err4 == nil {
t.Fatalf("[FAIL] should have failed to read empty file")
}
}
)
func TestSum(t *testing.T) {
t.Parallel()
if Sum(TypeNull, []byte("yeet")) != nil {
t.Fatal("Sum(TypeNull, []byte(\"yeet\")) should have returned nil")
}
var (
ogsha1, _ = base64.StdEncoding.DecodeString(kayosSHA1)
ogsha256, _ = base64.StdEncoding.DecodeString(kayosSHA256)
ogsha512, _ = base64.StdEncoding.DecodeString(kayosSHA512)
ogmd5, _ = base64.StdEncoding.DecodeString(kayosMD5)
newsha1 = Sum(TypeSHA1, []byte("kayos\n"))
newsha256 = Sum(TypeSHA256, []byte("kayos\n"))
newsha512 = Sum(TypeSHA512, []byte("kayos\n"))
newmd5 = Sum(TypeMD5, []byte("kayos\n"))
)
if !bytes.Equal(newsha1, ogsha1) {
t.Fatalf("[sha1] wanted: %v, got %v", ogsha1, newsha1)
for k, v := range valids {
typeToTest := k
valueToTest := v
t.Run(typeToTest.String()+"/string_check", func(t *testing.T) {
t.Parallel()
if !strings.EqualFold(typeToTest.String(), StringToType(typeToTest.String()).String()) {
t.Errorf("[FAIL] %s: wanted %s, got %s",
typeToTest.String(), typeToTest.String(), StringToType(typeToTest.String()).String(),
)
}
})
t.Run(typeToTest.String()+"/static_check", func(t *testing.T) {
t.Parallel()
mySum := Sum(typeToTest, kayosByteSlice)
if !bytes.Equal(mySum, valueToTest) {
t.Errorf("[FAIL] %s: wanted %v, got %v", typeToTest.String(), valueToTest, mySum)
}
})
t.Run(typeToTest.String()+"/file_check", func(t *testing.T) {
t.Parallel()
path := filepath.Join(t.TempDir(), typeToTest.String()) // for coverage
if err := os.WriteFile(path, kayosByteSlice, os.ModePerm); err != nil {
t.Fatalf("[FAIL] failed to write test fle for TestSum: %s", err.Error())
}
res, err := SumFile(typeToTest, path)
if err != nil {
t.Fatalf("[FAIL] failed to read test fle for TestSum: %s", err.Error())
}
if !bytes.Equal(res, valueToTest) {
t.Errorf("[FAIL] %s: wanted %v, got %v", typeToTest.String(), valueToTest, res)
}
})
}
t.Run("bad file", func(t *testing.T) {
t.Parallel()
_, err := SumFile(TypeSHA1, "/dev/null")
if err == nil {
t.Fatal("SumFile should have returned an error")
}
if _, err = SumFile(TypeSHA1, entropy.RandStrWithUpper(500)); err == nil {
t.Fatal("SumFile should have returned an error")
}
})
t.Run("unknown type", func(t *testing.T) {
t.Parallel()
if Type(uint8(94)).String() != "unknown" {
t.Fatal("Type(uint(9453543)).String() should have returned \"unknown\"")
}
if StringToType(entropy.RandStr(10)) != TypeNull {
t.Fatal("bogus string should have returned TypeNull")
}
})
}
func BenchmarkSum(b *testing.B) {
runIt := func(length int) {
dat := []byte(entropy.RandStrWithUpper(length))
b.Run(strconv.Itoa(length)+"char", func(b *testing.B) {
for sumType := range valids {
b.Run(sumType.String(), func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
b.SetBytes(int64(len(dat)))
Sum(sumType, dat)
}
})
}
})
}
for i := 0; i != 5; i++ {
mult := 5
if i == 0 {
runIt(50)
continue
}
if i > 1 {
mult = (mult * 10) * i
}
if i > 3 {
mult = (mult * 100) * i
}
runIt(i * mult)
}
t.Logf("[sha1] success: %s", kayosSHA1)
if !bytes.Equal(newsha256, ogsha256) {
t.Fatalf("[sha256] wanted: %v, got %v", ogsha256, newsha256)
}
t.Logf("[sha256] success: %s", kayosSHA256)
if !bytes.Equal(newsha512, ogsha512) {
t.Fatalf("[sha512] wanted: %v, got %v", ogsha512, newsha512)
}
t.Logf("[sha512] success: %s", kayosSHA512)
if !bytes.Equal(newmd5, ogmd5) {
t.Fatalf("[md5] wanted: %v, got %v", ogmd5, newmd5)
}
t.Logf("[md5] success: %s", kayosMD5)
}

19
pool/interface.go Normal file

@ -0,0 +1,19 @@
package pool
type Pool[T any] interface {
Get() T
Put(T)
}
type WithPutError[T any] interface {
Get() T
Put(T) error
}
type BufferFactoryInterfaceCompat struct {
BufferFactory
}
func (b BufferFactoryInterfaceCompat) Put(buf *Buffer) {
_ = b.BufferFactory.Put(buf)
}

68
pool/interface_test.go Normal file

@ -0,0 +1,68 @@
package pool
import (
"bytes"
"sync"
"testing"
)
// ensure compatibility with interface
func TestInterfaces(t *testing.T) {
t.Parallel()
defer func() {
if r := recover(); r != nil {
t.Error("interface not implemented")
}
}()
var (
bf any = NewBufferFactory()
bfCompat any = BufferFactoryInterfaceCompat{NewBufferFactory()}
sPool any = &sync.Pool{
New: func() any { return new(bytes.Buffer) },
}
)
if _, ok := sPool.(Pool[any]); !ok {
t.Fatal("Pool[any] not implemented by sync.Pool")
}
testMe1, ok1 := bfCompat.(Pool[*Buffer])
if !ok1 {
t.Fatal("Pool[*Buffer] not implemented")
}
t.Run("Pool", func(t *testing.T) {
t.Parallel()
b := testMe1.Get()
if _, err := b.WriteString("test"); err != nil {
t.Fatal(err)
}
testMe1.Put(b)
b = testMe1.Get()
if b.Len() != 0 {
t.Fatal("buffer not reset")
}
testMe1.Put(b)
})
t.Run("PoolWithPutError", func(t *testing.T) {
t.Parallel()
testMe2, ok2 := bf.(WithPutError[*Buffer])
if !ok2 {
t.Error("PoolWithPutError[*Buffer] not implemented")
}
b := testMe2.Get()
if _, err := b.WriteString("test"); err != nil {
t.Fatal(err)
}
if err := testMe2.Put(b); err != nil {
t.Fatal(err)
}
b = testMe2.Get()
if b.Len() != 0 {
t.Fatal("buffer not reset")
}
if err := testMe2.Put(b); err != nil {
t.Fatal(err)
}
})
}