rewrite hash

This commit is contained in:
Akvicor 2024-01-18 22:34:19 +08:00
parent 1e5dd01a83
commit d737b76456
10 changed files with 1058 additions and 142 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
.idea
testfile

View File

@ -1,25 +1,18 @@
# Util
- [x] Bytes to Uint (BigEndian)
- [x] Uint to Bytes (uint8-64)
- [x] Bytes Combine
- [x] Bit Set (uint8-64)
- [x] CRC32 (text/file)
- [x] MD5 (text/file)
- [x] SHA256 (text/file)
- [x] terminal multi-line input/edit
# Installation
Use the alias "util". To use Util in your Go code:
```go
import "github.com/AkvicorEdwards/util"
```
To install Util in your $GOPATH:
```shell script
go get "github.com/AkvicorEdwards/util"
import "git.viry.cc/gomod/util"
```
- [ ] CRC32
- [x] MD5
- [x] SHA1
- [x] SHA256
- [x] SHA512
- [ ] Base64
- [ ] bytes to int
- [ ] int to bytes
- [ ] Bytes Combine
- [ ] Bit Set
- [ ] Random String
- [ ] terminal multi-line input/edit

158
md5.go
View File

@ -1,45 +1,137 @@
package util
import (
"crypto/md5"
"errors"
"io"
"log"
"os"
"crypto/md5"
"encoding/hex"
"errors"
"hash"
"io"
"math"
"os"
"strings"
)
func MD5File(filePath string) ([16]byte, error) {
file, err := os.Open(filePath)
if err != nil {
return [16]byte{}, err
}
defer func() {
err := file.Close()
if err != nil {
log.Print(err)
}
}()
return MD5FileIO(file)
const MD5ResultLength = 16
type MD5Result struct {
result [MD5ResultLength]byte
err error
}
func MD5FileIO(file *os.File) ([16]byte, error) {
hash := md5.New()
if _, err := io.Copy(hash, file); err != nil {
return [16]byte{}, err
}
hashInBytes := hash.Sum(nil)
if len(hashInBytes) != 16 {
return [16]byte{}, errors.New("wrong length")
}
res := [16]byte{}
copy(res[:], hashInBytes)
return res, nil
func (m *MD5Result) Array() [MD5ResultLength]byte {
return m.result
}
func MD5String(str string) [16]byte {
return md5.Sum([]byte(str))
func (m *MD5Result) Slice() []byte {
return m.result[:]
}
func MD5Bytes(b []byte) [16]byte {
return md5.Sum(b)
func (m *MD5Result) Upper() string {
return strings.ToUpper(hex.EncodeToString(m.result[:]))
}
func (m *MD5Result) Lower() string {
return strings.ToLower(hex.EncodeToString(m.result[:]))
}
func (m *MD5Result) Error() error {
return m.err
}
func NewMD5Result(result []byte, err error) *MD5Result {
res := &MD5Result{
result: [MD5ResultLength]byte{},
err: err,
}
copy(res.result[:], result)
return res
}
type MD5 struct{}
func (m MD5) FromReader(r io.Reader) *MD5Result {
ha := md5.New()
if _, err := io.Copy(ha, r); err != nil {
return NewMD5Result(nil, err)
}
hashInBytes := ha.Sum(nil)
if len(hashInBytes) != MD5ResultLength {
return NewMD5Result(nil, errors.New("wrong length"))
}
return NewMD5Result(hashInBytes, nil)
}
func (m MD5) FromFile(filepath string) *MD5Result {
file, err := os.Open(filepath)
if err != nil {
return NewMD5Result(nil, err)
}
defer func() {
_ = file.Close()
}()
return m.FromReader(file)
}
func (m MD5) FromFileChunk(filepath string, chunkSize uint64) *MD5Result {
file, err := os.Open(filepath)
if err != nil {
return NewMD5Result(nil, err)
}
defer func() {
_ = file.Close()
}()
info, err := file.Stat()
if err != nil {
return NewMD5Result(nil, err)
}
filesize := info.Size()
blocks := uint64(math.Ceil(float64(filesize) / float64(chunkSize)))
ha := md5.New()
for i := uint64(0); i < blocks; i++ {
blockSize := int(math.Min(float64(chunkSize), float64(filesize-int64(i*chunkSize))))
buf := make([]byte, blockSize)
_, err = file.Read(buf)
if err != nil {
return NewMD5Result(nil, err)
}
_, err = ha.Write(buf)
if err != nil {
return NewMD5Result(nil, err)
}
}
return NewMD5Result(ha.Sum(nil), nil)
}
func (m MD5) FromBytes(b []byte) *MD5Result {
res := md5.Sum(b)
return NewMD5Result(res[:], nil)
}
func (m MD5) FromString(str string) *MD5Result {
res := md5.Sum([]byte(str))
return NewMD5Result(res[:], nil)
}
type MD5Pip struct {
md5 hash.Hash
}
func NewMD5Pip() *MD5Pip {
return &MD5Pip{md5: md5.New()}
}
func (m *MD5Pip) Write(data []byte) error {
_, err := m.md5.Write(data)
return err
}
func (m *MD5Pip) WriteString(data string) error {
_, err := m.md5.Write([]byte(data))
return err
}
func (m *MD5Pip) Result() *MD5Result {
return NewMD5Result(m.md5.Sum(nil), nil)
}

View File

@ -1,33 +1,133 @@
package util
import (
"fmt"
"log"
"bytes"
"encoding/hex"
"strings"
"testing"
)
func ExampleMD5File() {
// dd if=/dev/zero of=testFile1 bs=3M count=2
bs, err := MD5File("testFile1")
if err != nil {
log.Println(err)
return
}
fmt.Printf("%x\n", bs)
// Output:
// da6a0d097e307ac52ed9b4ad551801fc
}
func ExampleMD5String() {
fmt.Printf("%x\n", MD5String("Hello MD5"))
// Output:
// e5dadf6524624f79c3127e247f04b548
}
func ExampleMD5Bytes() {
fmt.Printf("%x\n", MD5Bytes([]byte("Hello MD5")))
// Output:
// e5dadf6524624f79c3127e247f04b548
func TestMD5(t *testing.T) {
// dd if=/dev/random of=testfile/testFile1 bs=4KB count=4
// md5sum testFile1
const fileMD5 = "d44c695aa41c925c6e26979501cafdaa"
fileMD5Bytes, err := hex.DecodeString(fileMD5)
if err != nil {
t.Errorf("fileMD5Bytes: %v", err)
}
testString := "Akvicor"
testBytes := []byte(testString)
testStringP1 := "Akv"
testStringP2 := "icor"
testBytesP1 := []byte(testStringP1)
testBytesP2 := []byte(testStringP2)
testMD5 := "f812705c26adc52561415189e5f78edb"
testMD5P1 := "d1c13e1e2aa77bed0a694fe1b375a3aa"
// test FromFile & MD5Result
m5 := MD5{}.FromFile("testfile/testFile1")
if m5.Error() != nil {
t.Errorf("FromFile failed: %v", m5.Error())
}
if m5.Lower() != fileMD5 {
t.Errorf("FromFile failed: need: [%s] got [%s]", fileMD5, m5.Lower())
}
if m5.Upper() != strings.ToUpper(fileMD5) {
t.Errorf("FromFile failed: need: [%s] got [%s]", strings.ToUpper(fileMD5), m5.Upper())
}
if !bytes.Equal(m5.Slice(), fileMD5Bytes) {
t.Errorf("FromFile failed: need: [%v] got [%v]", fileMD5Bytes, m5.Slice())
}
ay := m5.Array()
if !bytes.Equal(ay[:], fileMD5Bytes) {
t.Errorf("FromFile failed: need: [%v] got [%v]", fileMD5Bytes, ay)
}
// test FromFileChunk
m5 = MD5{}.FromFileChunk("testfile/testFile1", 1024)
if m5.Error() != nil {
t.Errorf("FromFileChunk failed: %v", m5.Error())
}
if m5.Lower() != fileMD5 {
t.Errorf("FromFileChunk failed: need: [%s] got [%s]", fileMD5, m5.Lower())
}
// test FromBytes
m5 = MD5{}.FromBytes(testBytes)
if m5.Error() != nil {
t.Errorf("FromBytes failed: %v", m5.Error())
}
if m5.Lower() != testMD5 {
t.Errorf("FromBytes failed: need: [%s] got [%s]", testMD5, m5.Lower())
}
// test FromString
m5 = MD5{}.FromString(testString)
if m5.Error() != nil {
t.Errorf("FromString failed: %v", m5.Error())
}
if m5.Lower() != testMD5 {
t.Errorf("FromString failed: need: [%s] got [%s]", testMD5, m5.Lower())
}
// test NewMD5Pip.Write
mp := NewMD5Pip()
err = mp.Write(testBytesP1)
if err != nil {
t.Errorf("NewMD5Pip Write failed: %v", err)
}
err = mp.Write(testBytesP2)
if err != nil {
t.Errorf("NewMD5Pip Write failed: %v", err)
}
m5 = mp.Result()
if m5.Error() != nil {
t.Errorf("NewMD5Pip Write failed: %v", m5.Error())
}
if m5.Lower() != testMD5 {
t.Errorf("NewMD5Pip Write failed: need: [%s] got [%s]", testMD5, m5.Lower())
}
// test NewMD5Pip.WriteString
mp = NewMD5Pip()
err = mp.WriteString(testStringP1)
if err != nil {
t.Errorf("NewMD5Pip WriteString failed: %v", err)
}
err = mp.WriteString(testStringP2)
if err != nil {
t.Errorf("NewMD5Pip WriteString failed: %v", err)
}
m5 = mp.Result()
if m5.Error() != nil {
t.Errorf("NewMD5Pip WriteString failed: %v", m5.Error())
}
if m5.Lower() != testMD5 {
t.Errorf("NewMD5Pip WriteString failed: need: [%s] got [%s]", testMD5, m5.Lower())
}
// test NewMD5Pip.Result
mp = NewMD5Pip()
err = mp.WriteString(testStringP1)
if err != nil {
t.Errorf("NewMD5Pip WriteString failed: %v", err)
}
m5 = mp.Result()
if m5.Error() != nil {
t.Errorf("NewMD5Pip WriteString failed: %v", m5.Error())
}
if m5.Lower() != testMD5P1 {
t.Errorf("NewMD5Pip WriteString failed: need: [%s] got [%s]", testMD5P1, m5.Lower())
}
err = mp.WriteString(testStringP2)
if err != nil {
t.Errorf("NewMD5Pip WriteString failed: %v", err)
}
m5 = mp.Result()
if m5.Error() != nil {
t.Errorf("NewMD5Pip WriteString failed: %v", m5.Error())
}
if m5.Lower() != testMD5 {
t.Errorf("NewMD5Pip WriteString failed: need: [%s] got [%s]", testMD5, m5.Lower())
}
}

137
sha1.go Normal file
View File

@ -0,0 +1,137 @@
package util
import (
"crypto/sha1"
"encoding/hex"
"errors"
"hash"
"io"
"math"
"os"
"strings"
)
const SHA1ResultLength = 20
type SHA1Result struct {
result [SHA1ResultLength]byte
err error
}
func (s *SHA1Result) Array() [SHA1ResultLength]byte {
return s.result
}
func (s *SHA1Result) Slice() []byte {
return s.result[:]
}
func (s *SHA1Result) Upper() string {
return strings.ToUpper(hex.EncodeToString(s.result[:]))
}
func (s *SHA1Result) Lower() string {
return strings.ToLower(hex.EncodeToString(s.result[:]))
}
func (s *SHA1Result) Error() error {
return s.err
}
func NewSHA1Result(result []byte, err error) *SHA1Result {
res := &SHA1Result{
result: [SHA1ResultLength]byte{},
err: err,
}
copy(res.result[:], result)
return res
}
type SHA1 struct{}
func (s SHA1) FromReader(r io.Reader) *SHA1Result {
ha := sha1.New()
if _, err := io.Copy(ha, r); err != nil {
return NewSHA1Result(nil, err)
}
hashInBytes := ha.Sum(nil)
if len(hashInBytes) != SHA1ResultLength {
return NewSHA1Result(nil, errors.New("wrong length"))
}
return NewSHA1Result(hashInBytes, nil)
}
func (s SHA1) FromFile(filepath string) *SHA1Result {
file, err := os.Open(filepath)
if err != nil {
return NewSHA1Result(nil, err)
}
defer func() {
_ = file.Close()
}()
return s.FromReader(file)
}
func (s SHA1) FromFileChunk(filepath string, chunkSize uint64) *SHA1Result {
file, err := os.Open(filepath)
if err != nil {
return NewSHA1Result(nil, err)
}
defer func() {
_ = file.Close()
}()
info, err := file.Stat()
if err != nil {
return NewSHA1Result(nil, err)
}
filesize := info.Size()
blocks := uint64(math.Ceil(float64(filesize) / float64(chunkSize)))
ha := sha1.New()
for i := uint64(0); i < blocks; i++ {
blockSize := int(math.Min(float64(chunkSize), float64(filesize-int64(i*chunkSize))))
buf := make([]byte, blockSize)
_, err = file.Read(buf)
if err != nil {
return NewSHA1Result(nil, err)
}
_, err = ha.Write(buf)
if err != nil {
return NewSHA1Result(nil, err)
}
}
return NewSHA1Result(ha.Sum(nil), nil)
}
func (s SHA1) FromBytes(b []byte) *SHA1Result {
res := sha1.Sum(b)
return NewSHA1Result(res[:], nil)
}
func (s SHA1) FromString(str string) *SHA1Result {
res := sha1.Sum([]byte(str))
return NewSHA1Result(res[:], nil)
}
type SHA1Pip struct {
sha1 hash.Hash
}
func NewSHA1Pip() *SHA1Pip {
return &SHA1Pip{sha1: sha1.New()}
}
func (s *SHA1Pip) Write(data []byte) error {
_, err := s.sha1.Write(data)
return err
}
func (s *SHA1Pip) WriteString(data string) error {
_, err := s.sha1.Write([]byte(data))
return err
}
func (s *SHA1Pip) Result() *SHA1Result {
return NewSHA1Result(s.sha1.Sum(nil), nil)
}

133
sha1_test.go Normal file
View File

@ -0,0 +1,133 @@
package util
import (
"bytes"
"encoding/hex"
"strings"
"testing"
)
func TestSHA1(t *testing.T) {
// dd if=/dev/random of=testfile/testFile1 bs=4KB count=4
// sha1sum testFile1
const fileSHA1 = "30472a6c6f2638a3ebc65ce6bd623a42849a9f4b"
testString := "Akvicor"
testStringP1 := "Akv"
testStringP2 := "icor"
testSHA1 := "49296886bfedac0dd0399030bc0dbe12e5eed489"
testSHA1P1 := "0b4e8f1f52b4ae507d2683e760a168bbbd94eef4"
testBytes := []byte(testString)
testBytesP1 := []byte(testStringP1)
testBytesP2 := []byte(testStringP2)
fileSHA1Bytes, err := hex.DecodeString(fileSHA1)
if err != nil {
t.Errorf("fileSHA1Bytes: %v", err)
}
// test FromFile & SHA1Result
s1 := SHA1{}.FromFile("testfile/testFile1")
if s1.Error() != nil {
t.Errorf("FromFile failed: %v", s1.Error())
}
if s1.Lower() != fileSHA1 {
t.Errorf("FromFile failed: need: [%s] got [%s]", fileSHA1, s1.Lower())
}
if s1.Upper() != strings.ToUpper(fileSHA1) {
t.Errorf("FromFile failed: need: [%s] got [%s]", strings.ToUpper(fileSHA1), s1.Upper())
}
if !bytes.Equal(s1.Slice(), fileSHA1Bytes) {
t.Errorf("FromFile failed: need: [%v] got [%v]", fileSHA1Bytes, s1.Slice())
}
ay := s1.Array()
if !bytes.Equal(ay[:], fileSHA1Bytes) {
t.Errorf("FromFile failed: need: [%v] got [%v]", fileSHA1Bytes, ay)
}
// test FromFileChunk
s1 = SHA1{}.FromFileChunk("testfile/testFile1", 1024)
if s1.Error() != nil {
t.Errorf("FromFileChunk failed: %v", s1.Error())
}
if s1.Lower() != fileSHA1 {
t.Errorf("FromFileChunk failed: need: [%s] got [%s]", fileSHA1, s1.Lower())
}
// test FromBytes
s1 = SHA1{}.FromBytes(testBytes)
if s1.Error() != nil {
t.Errorf("FromBytes failed: %v", s1.Error())
}
if s1.Lower() != testSHA1 {
t.Errorf("FromBytes failed: need: [%s] got [%s]", testSHA1, s1.Lower())
}
// test FromString
s1 = SHA1{}.FromString(testString)
if s1.Error() != nil {
t.Errorf("FromString failed: %v", s1.Error())
}
if s1.Lower() != testSHA1 {
t.Errorf("FromString failed: need: [%s] got [%s]", testSHA1, s1.Lower())
}
// test NewSHA1Pip.Write
mp := NewSHA1Pip()
err = mp.Write(testBytesP1)
if err != nil {
t.Errorf("NewSHA1Pip Write failed: %v", err)
}
err = mp.Write(testBytesP2)
if err != nil {
t.Errorf("NewSHA1Pip Write failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA1Pip Write failed: %v", s1.Error())
}
if s1.Lower() != testSHA1 {
t.Errorf("NewSHA1Pip Write failed: need: [%s] got [%s]", testSHA1, s1.Lower())
}
// test NewSHA1Pip.WriteString
mp = NewSHA1Pip()
err = mp.WriteString(testStringP1)
if err != nil {
t.Errorf("NewSHA1Pip WriteString failed: %v", err)
}
err = mp.WriteString(testStringP2)
if err != nil {
t.Errorf("NewSHA1Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA1Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA1 {
t.Errorf("NewSHA1Pip WriteString failed: need: [%s] got [%s]", testSHA1, s1.Lower())
}
// test NewSHA1Pip.Result
mp = NewSHA1Pip()
err = mp.WriteString(testStringP1)
if err != nil {
t.Errorf("NewSHA1Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA1Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA1P1 {
t.Errorf("NewSHA1Pip WriteString failed: need: [%s] got [%s]", testSHA1P1, s1.Lower())
}
err = mp.WriteString(testStringP2)
if err != nil {
t.Errorf("NewSHA1Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA1Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA1 {
t.Errorf("NewSHA1Pip WriteString failed: need: [%s] got [%s]", testSHA1, s1.Lower())
}
}

160
sha256.go
View File

@ -1,47 +1,137 @@
package util
import (
"crypto/sha256"
"errors"
"io"
"log"
"os"
"crypto/sha256"
"encoding/hex"
"errors"
"hash"
"io"
"math"
"os"
"strings"
)
func SHA256File(filePath string) ([32]byte, error) {
file, err := os.Open(filePath)
if err != nil {
return [32]byte{}, err
}
defer func() {
err := file.Close()
if err != nil {
log.Print(err)
}
}()
return SHA256FileIO(file)
const SHA256ResultLength = 32
type SHA256Result struct {
result [SHA256ResultLength]byte
err error
}
func SHA256FileIO(file *os.File) ([32]byte, error) {
hash := sha256.New()
if _, err := io.Copy(hash, file); err != nil {
return [32]byte{}, err
}
hashInBytes := hash.Sum(nil)
if len(hashInBytes) != 32 {
return [32]byte{}, errors.New("wrong length")
}
res := [32]byte{}
copy(res[:], hashInBytes)
return res, nil
func (s *SHA256Result) Array() [SHA256ResultLength]byte {
return s.result
}
func SHA256String(str string) [32]byte {
data := sha256.Sum256([]byte(str))
return data
func (s *SHA256Result) Slice() []byte {
return s.result[:]
}
func SHA256Bytes(str []byte) [32]byte {
data := sha256.Sum256(str)
return data
func (s *SHA256Result) Upper() string {
return strings.ToUpper(hex.EncodeToString(s.result[:]))
}
func (s *SHA256Result) Lower() string {
return strings.ToLower(hex.EncodeToString(s.result[:]))
}
func (s *SHA256Result) Error() error {
return s.err
}
func NewSHA256Result(result []byte, err error) *SHA256Result {
res := &SHA256Result{
result: [SHA256ResultLength]byte{},
err: err,
}
copy(res.result[:], result)
return res
}
type SHA256 struct{}
func (s SHA256) FromReader(r io.Reader) *SHA256Result {
ha := sha256.New()
if _, err := io.Copy(ha, r); err != nil {
return NewSHA256Result(nil, err)
}
hashInBytes := ha.Sum(nil)
if len(hashInBytes) != SHA256ResultLength {
return NewSHA256Result(nil, errors.New("wrong length"))
}
return NewSHA256Result(hashInBytes, nil)
}
func (s SHA256) FromFile(filepath string) *SHA256Result {
file, err := os.Open(filepath)
if err != nil {
return NewSHA256Result(nil, err)
}
defer func() {
_ = file.Close()
}()
return s.FromReader(file)
}
func (s SHA256) FromFileChunk(filepath string, chunkSize uint64) *SHA256Result {
file, err := os.Open(filepath)
if err != nil {
return NewSHA256Result(nil, err)
}
defer func() {
_ = file.Close()
}()
info, err := file.Stat()
if err != nil {
return NewSHA256Result(nil, err)
}
filesize := info.Size()
blocks := uint64(math.Ceil(float64(filesize) / float64(chunkSize)))
ha := sha256.New()
for i := uint64(0); i < blocks; i++ {
blockSize := int(math.Min(float64(chunkSize), float64(filesize-int64(i*chunkSize))))
buf := make([]byte, blockSize)
_, err = file.Read(buf)
if err != nil {
return NewSHA256Result(nil, err)
}
_, err = ha.Write(buf)
if err != nil {
return NewSHA256Result(nil, err)
}
}
return NewSHA256Result(ha.Sum(nil), nil)
}
func (s SHA256) FromBytes(b []byte) *SHA256Result {
res := sha256.Sum256(b)
return NewSHA256Result(res[:], nil)
}
func (s SHA256) FromString(str string) *SHA256Result {
res := sha256.Sum256([]byte(str))
return NewSHA256Result(res[:], nil)
}
type SHA256Pip struct {
sha256 hash.Hash
}
func NewSHA256Pip() *SHA256Pip {
return &SHA256Pip{sha256: sha256.New()}
}
func (s *SHA256Pip) Write(data []byte) error {
_, err := s.sha256.Write(data)
return err
}
func (s *SHA256Pip) WriteString(data string) error {
_, err := s.sha256.Write([]byte(data))
return err
}
func (s *SHA256Pip) Result() *SHA256Result {
return NewSHA256Result(s.sha256.Sum(nil), nil)
}

View File

@ -1,33 +1,133 @@
package util
import (
"fmt"
"log"
"bytes"
"encoding/hex"
"strings"
"testing"
)
func ExampleSHA256File() {
// dd if=/dev/zero of=testFile1 bs=3M count=2
bs, err := SHA256File("testFile1")
if err != nil {
log.Println(err)
return
}
fmt.Printf("%x\n", bs)
// Output:
// b69dae56a14d1a8314ed40664c4033ea0a550eea2673e04df42a66ac6b9faf2c
}
func ExampleSHA256String() {
fmt.Printf("%x\n", SHA256String("Hello Sha256"))
// Output:
// b689b7eb84fe084725de196e09481d4fad8d2c50c99fb6a33739543a5ca250e2
}
func ExampleSHA256Bytes() {
fmt.Printf("%x\n", SHA256Bytes([]byte("Hello Sha256")))
// Output:
// b689b7eb84fe084725de196e09481d4fad8d2c50c99fb6a33739543a5ca250e2
func TestSHA256(t *testing.T) {
// dd if=/dev/random of=testfile/testFile1 bs=4KB count=4
// sha256sum testFile1
const fileSHA256 = "0aa203abf8927c5a91062311a246ccaaaf038e6bc3a25ea62a978ed5d280698a"
testString := "Akvicor"
testStringP1 := "Akv"
testStringP2 := "icor"
testSHA256 := "36acc0924a190c77386cd819a3bff60251345e8654399f68e8b740a1afa62ff5"
testSHA256P1 := "5a01f2f1bd960f10e647fb9c78797836a9774683469ef759c303cd2934548563"
testBytes := []byte(testString)
testBytesP1 := []byte(testStringP1)
testBytesP2 := []byte(testStringP2)
fileSHA256Bytes, err := hex.DecodeString(fileSHA256)
if err != nil {
t.Errorf("fileSHA256Bytes: %v", err)
}
// test FromFile & SHA256Result
s1 := SHA256{}.FromFile("testfile/testFile1")
if s1.Error() != nil {
t.Errorf("FromFile failed: %v", s1.Error())
}
if s1.Lower() != fileSHA256 {
t.Errorf("FromFile failed: need: [%s] got [%s]", fileSHA256, s1.Lower())
}
if s1.Upper() != strings.ToUpper(fileSHA256) {
t.Errorf("FromFile failed: need: [%s] got [%s]", strings.ToUpper(fileSHA256), s1.Upper())
}
if !bytes.Equal(s1.Slice(), fileSHA256Bytes) {
t.Errorf("FromFile failed: need: [%v] got [%v]", fileSHA256Bytes, s1.Slice())
}
ay := s1.Array()
if !bytes.Equal(ay[:], fileSHA256Bytes) {
t.Errorf("FromFile failed: need: [%v] got [%v]", fileSHA256Bytes, ay)
}
// test FromFileChunk
s1 = SHA256{}.FromFileChunk("testfile/testFile1", 1024)
if s1.Error() != nil {
t.Errorf("FromFileChunk failed: %v", s1.Error())
}
if s1.Lower() != fileSHA256 {
t.Errorf("FromFileChunk failed: need: [%s] got [%s]", fileSHA256, s1.Lower())
}
// test FromBytes
s1 = SHA256{}.FromBytes(testBytes)
if s1.Error() != nil {
t.Errorf("FromBytes failed: %v", s1.Error())
}
if s1.Lower() != testSHA256 {
t.Errorf("FromBytes failed: need: [%s] got [%s]", testSHA256, s1.Lower())
}
// test FromString
s1 = SHA256{}.FromString(testString)
if s1.Error() != nil {
t.Errorf("FromString failed: %v", s1.Error())
}
if s1.Lower() != testSHA256 {
t.Errorf("FromString failed: need: [%s] got [%s]", testSHA256, s1.Lower())
}
// test NewSHA256Pip.Write
mp := NewSHA256Pip()
err = mp.Write(testBytesP1)
if err != nil {
t.Errorf("NewSHA256Pip Write failed: %v", err)
}
err = mp.Write(testBytesP2)
if err != nil {
t.Errorf("NewSHA256Pip Write failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA256Pip Write failed: %v", s1.Error())
}
if s1.Lower() != testSHA256 {
t.Errorf("NewSHA256Pip Write failed: need: [%s] got [%s]", testSHA256, s1.Lower())
}
// test NewSHA256Pip.WriteString
mp = NewSHA256Pip()
err = mp.WriteString(testStringP1)
if err != nil {
t.Errorf("NewSHA256Pip WriteString failed: %v", err)
}
err = mp.WriteString(testStringP2)
if err != nil {
t.Errorf("NewSHA256Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA256Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA256 {
t.Errorf("NewSHA256Pip WriteString failed: need: [%s] got [%s]", testSHA256, s1.Lower())
}
// test NewSHA256Pip.Result
mp = NewSHA256Pip()
err = mp.WriteString(testStringP1)
if err != nil {
t.Errorf("NewSHA256Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA256Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA256P1 {
t.Errorf("NewSHA256Pip WriteString failed: need: [%s] got [%s]", testSHA256P1, s1.Lower())
}
err = mp.WriteString(testStringP2)
if err != nil {
t.Errorf("NewSHA256Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA256Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA256 {
t.Errorf("NewSHA256Pip WriteString failed: need: [%s] got [%s]", testSHA256, s1.Lower())
}
}

137
sha512.go Normal file
View File

@ -0,0 +1,137 @@
package util
import (
"crypto/sha512"
"encoding/hex"
"errors"
"hash"
"io"
"math"
"os"
"strings"
)
const SHA512ResultLength = 64
type SHA512Result struct {
result [SHA512ResultLength]byte
err error
}
func (s *SHA512Result) Array() [SHA512ResultLength]byte {
return s.result
}
func (s *SHA512Result) Slice() []byte {
return s.result[:]
}
func (s *SHA512Result) Upper() string {
return strings.ToUpper(hex.EncodeToString(s.result[:]))
}
func (s *SHA512Result) Lower() string {
return strings.ToLower(hex.EncodeToString(s.result[:]))
}
func (s *SHA512Result) Error() error {
return s.err
}
func NewSHA512Result(result []byte, err error) *SHA512Result {
res := &SHA512Result{
result: [SHA512ResultLength]byte{},
err: err,
}
copy(res.result[:], result)
return res
}
type SHA512 struct{}
func (s SHA512) FromReader(r io.Reader) *SHA512Result {
ha := sha512.New()
if _, err := io.Copy(ha, r); err != nil {
return NewSHA512Result(nil, err)
}
hashInBytes := ha.Sum(nil)
if len(hashInBytes) != SHA512ResultLength {
return NewSHA512Result(nil, errors.New("wrong length"))
}
return NewSHA512Result(hashInBytes, nil)
}
func (s SHA512) FromFile(filepath string) *SHA512Result {
file, err := os.Open(filepath)
if err != nil {
return NewSHA512Result(nil, err)
}
defer func() {
_ = file.Close()
}()
return s.FromReader(file)
}
func (s SHA512) FromFileChunk(filepath string, chunkSize uint64) *SHA512Result {
file, err := os.Open(filepath)
if err != nil {
return NewSHA512Result(nil, err)
}
defer func() {
_ = file.Close()
}()
info, err := file.Stat()
if err != nil {
return NewSHA512Result(nil, err)
}
filesize := info.Size()
blocks := uint64(math.Ceil(float64(filesize) / float64(chunkSize)))
ha := sha512.New()
for i := uint64(0); i < blocks; i++ {
blockSize := int(math.Min(float64(chunkSize), float64(filesize-int64(i*chunkSize))))
buf := make([]byte, blockSize)
_, err = file.Read(buf)
if err != nil {
return NewSHA512Result(nil, err)
}
_, err = ha.Write(buf)
if err != nil {
return NewSHA512Result(nil, err)
}
}
return NewSHA512Result(ha.Sum(nil), nil)
}
func (s SHA512) FromBytes(b []byte) *SHA512Result {
res := sha512.Sum512(b)
return NewSHA512Result(res[:], nil)
}
func (s SHA512) FromString(str string) *SHA512Result {
res := sha512.Sum512([]byte(str))
return NewSHA512Result(res[:], nil)
}
type SHA512Pip struct {
sha512 hash.Hash
}
func NewSHA512Pip() *SHA512Pip {
return &SHA512Pip{sha512: sha512.New()}
}
func (s *SHA512Pip) Write(data []byte) error {
_, err := s.sha512.Write(data)
return err
}
func (s *SHA512Pip) WriteString(data string) error {
_, err := s.sha512.Write([]byte(data))
return err
}
func (s *SHA512Pip) Result() *SHA512Result {
return NewSHA512Result(s.sha512.Sum(nil), nil)
}

133
sha512_test.go Normal file
View File

@ -0,0 +1,133 @@
package util
import (
"bytes"
"encoding/hex"
"strings"
"testing"
)
func TestSHA512(t *testing.T) {
// dd if=/dev/random of=testfile/testFile1 bs=4KB count=4
// sha512sum testFile1
const fileSHA512 = "9b5ca4ca0bd1c835bbf2cb9d9fa0de95107aea76735315fdf7628f30428fbbe7f4254029bb2d6229b7b035e732d4f6582a1a39eb5ae6820389e6de5f6e0f14e5"
testString := "Akvicor"
testStringP1 := "Akv"
testStringP2 := "icor"
testSHA512 := "6fdfb481af6573ac49d4031d22f0d73f0f24ea8cb113982593ec65ab085b0635b46d7683aa3f4ef36c2cb25a7bb8ba8cbae2fa3e9810d35b1c70a93f37586361"
testSHA512P1 := "3c7ec9519b880b2a6438dea41c4d49cb8761f167dadb237690799aae202852c688d7234f34fa8ff468b794cbfff542e5bd9c77a20f74db7aff7f0b716b49af9c"
testBytes := []byte(testString)
testBytesP1 := []byte(testStringP1)
testBytesP2 := []byte(testStringP2)
fileSHA512Bytes, err := hex.DecodeString(fileSHA512)
if err != nil {
t.Errorf("fileSHA512Bytes: %v", err)
}
// test FromFile & SHA512Result
s1 := SHA512{}.FromFile("testfile/testFile1")
if s1.Error() != nil {
t.Errorf("FromFile failed: %v", s1.Error())
}
if s1.Lower() != fileSHA512 {
t.Errorf("FromFile failed: need: [%s] got [%s]", fileSHA512, s1.Lower())
}
if s1.Upper() != strings.ToUpper(fileSHA512) {
t.Errorf("FromFile failed: need: [%s] got [%s]", strings.ToUpper(fileSHA512), s1.Upper())
}
if !bytes.Equal(s1.Slice(), fileSHA512Bytes) {
t.Errorf("FromFile failed: need: [%v] got [%v]", fileSHA512Bytes, s1.Slice())
}
ay := s1.Array()
if !bytes.Equal(ay[:], fileSHA512Bytes) {
t.Errorf("FromFile failed: need: [%v] got [%v]", fileSHA512Bytes, ay)
}
// test FromFileChunk
s1 = SHA512{}.FromFileChunk("testfile/testFile1", 1024)
if s1.Error() != nil {
t.Errorf("FromFileChunk failed: %v", s1.Error())
}
if s1.Lower() != fileSHA512 {
t.Errorf("FromFileChunk failed: need: [%s] got [%s]", fileSHA512, s1.Lower())
}
// test FromBytes
s1 = SHA512{}.FromBytes(testBytes)
if s1.Error() != nil {
t.Errorf("FromBytes failed: %v", s1.Error())
}
if s1.Lower() != testSHA512 {
t.Errorf("FromBytes failed: need: [%s] got [%s]", testSHA512, s1.Lower())
}
// test FromString
s1 = SHA512{}.FromString(testString)
if s1.Error() != nil {
t.Errorf("FromString failed: %v", s1.Error())
}
if s1.Lower() != testSHA512 {
t.Errorf("FromString failed: need: [%s] got [%s]", testSHA512, s1.Lower())
}
// test NewSHA512Pip.Write
mp := NewSHA512Pip()
err = mp.Write(testBytesP1)
if err != nil {
t.Errorf("NewSHA512Pip Write failed: %v", err)
}
err = mp.Write(testBytesP2)
if err != nil {
t.Errorf("NewSHA512Pip Write failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA512Pip Write failed: %v", s1.Error())
}
if s1.Lower() != testSHA512 {
t.Errorf("NewSHA512Pip Write failed: need: [%s] got [%s]", testSHA512, s1.Lower())
}
// test NewSHA512Pip.WriteString
mp = NewSHA512Pip()
err = mp.WriteString(testStringP1)
if err != nil {
t.Errorf("NewSHA512Pip WriteString failed: %v", err)
}
err = mp.WriteString(testStringP2)
if err != nil {
t.Errorf("NewSHA512Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA512Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA512 {
t.Errorf("NewSHA512Pip WriteString failed: need: [%s] got [%s]", testSHA512, s1.Lower())
}
// test NewSHA512Pip.Result
mp = NewSHA512Pip()
err = mp.WriteString(testStringP1)
if err != nil {
t.Errorf("NewSHA512Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA512Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA512P1 {
t.Errorf("NewSHA512Pip WriteString failed: need: [%s] got [%s]", testSHA512P1, s1.Lower())
}
err = mp.WriteString(testStringP2)
if err != nil {
t.Errorf("NewSHA512Pip WriteString failed: %v", err)
}
s1 = mp.Result()
if s1.Error() != nil {
t.Errorf("NewSHA512Pip WriteString failed: %v", s1.Error())
}
if s1.Lower() != testSHA512 {
t.Errorf("NewSHA512Pip WriteString failed: need: [%s] got [%s]", testSHA512, s1.Lower())
}
}