Feat/Refactor[hash]: !!BREAKING!! add CRC32 and general refactor !!BREAKING!!
This commit is contained in:
parent
9ecc1d1677
commit
fc8a72e617
@ -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 {
|
||||
|
55
hash/hash.go
55
hash/hash.go
@ -1,7 +1,6 @@
|
||||
package hash
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5" //nolint:gosec
|
||||
"crypto/sha1" //nolint:gosec
|
||||
"crypto/sha256"
|
||||
@ -9,6 +8,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
@ -25,8 +25,37 @@ const (
|
||||
TypeSHA256
|
||||
TypeSHA512
|
||||
TypeMD5
|
||||
TypeCRC32
|
||||
)
|
||||
|
||||
var typeToString = map[Type]string{
|
||||
TypeNull: "null", TypeBlake2b: "blake2b", TypeSHA1: "sha1",
|
||||
TypeSHA256: "sha256", TypeSHA512: "sha512",
|
||||
TypeMD5: "md5", TypeCRC32: "crc32",
|
||||
}
|
||||
|
||||
var stringToType = map[string]Type{
|
||||
"null": TypeNull, "blake2b": TypeBlake2b, "sha1": TypeSHA1,
|
||||
"sha256": TypeSHA256, "sha512": TypeSHA512,
|
||||
"md5": TypeMD5, "crc32": TypeCRC32,
|
||||
}
|
||||
|
||||
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 +83,11 @@ var (
|
||||
return h
|
||||
},
|
||||
}
|
||||
crc32Pool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return crc32.NewIEEE()
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func Sum(ht Type, b []byte) []byte {
|
||||
@ -74,6 +108,9 @@ 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)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@ -83,13 +120,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 +139,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,10 +4,11 @@ import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.tcp.direct/kayos/common/entropy"
|
||||
"git.tcp.direct/kayos/common/squish"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -16,89 +17,96 @@ const (
|
||||
kayosSHA1 = "M23ElC0sQYAK+MaMZVmza2L8mss="
|
||||
kayosSHA256 = "BagY0TmoGR3O7t80BGm4K6UHPlqEg6HJirwQmhrPK4U="
|
||||
kayosSHA512 = "xiuo2na76acrWXCTTR++O1pPZabOhyj8nbfb5Go3e1pEq9VJYIsOioTXalf2GCuERmFecWkmaL5QI8mIXXWpNA=="
|
||||
kayosCRC32 = "xtig5w=="
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
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")
|
||||
}
|
||||
}
|
||||
var kayosByteSlice = []byte{107, 97, 121, 111, 115, 10}
|
||||
|
||||
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"))
|
||||
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)
|
||||
valids = map[Type][]byte{
|
||||
TypeSHA1: ogsha1,
|
||||
TypeSHA256: ogsha256,
|
||||
TypeSHA512: ogsha512,
|
||||
TypeMD5: ogmd5,
|
||||
TypeCRC32: ogCRC32,
|
||||
TypeBlake2b: ogBlake2b,
|
||||
}
|
||||
)
|
||||
|
||||
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")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var benchData = []byte(entropy.RandStrWithUpper(5000))
|
||||
|
||||
func BenchmarkSum(b *testing.B) {
|
||||
for _, sumType := range []Type{TypeSHA1, TypeSHA256, TypeSHA512, TypeBlake2b, TypeMD5} {
|
||||
b.Run(sumType.String(), func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.SetBytes(int64(len(benchData)))
|
||||
Sum(sumType, benchData)
|
||||
}
|
||||
})
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user