Skip to content

Commit

Permalink
👔 up: str - update bytes util and add new hash utils
Browse files Browse the repository at this point in the history
- HashPasswd
- VerifyPasswd
  • Loading branch information
inhere committed Dec 8, 2022
1 parent e5a08d4 commit 8eef351
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 137 deletions.
110 changes: 5 additions & 105 deletions strutil/bytes.go
@@ -1,69 +1,17 @@
package strutil

import (
"bytes"
"fmt"
"strings"
"github.com/gookit/goutil/byteutil"
)

// Buffer wrap and extends the bytes.Buffer
type Buffer struct {
bytes.Buffer
}
type Buffer = byteutil.Buffer

// NewBuffer instance
func NewBuffer() *Buffer {
return &Buffer{}
}

// WriteAny type value to buffer
func (b *Buffer) WriteAny(vs ...any) {
for _, v := range vs {
_, _ = b.Buffer.WriteString(fmt.Sprint(v))
}
}

// QuietWriteByte to buffer
func (b *Buffer) QuietWriteByte(c byte) {
_ = b.WriteByte(c)
}

// QuietWritef write message to buffer
func (b *Buffer) QuietWritef(tpl string, vs ...any) {
_, _ = b.WriteString(fmt.Sprintf(tpl, vs...))
}

// Writeln write message to buffer with newline
func (b *Buffer) Writeln(ss ...string) {
b.QuietWriteln(ss...)
}

// QuietWriteln write message to buffer with newline
func (b *Buffer) QuietWriteln(ss ...string) {
_, _ = b.WriteString(strings.Join(ss, ""))
_ = b.WriteByte('\n')
}

// QuietWriteString to buffer
func (b *Buffer) QuietWriteString(ss ...string) {
_, _ = b.WriteString(strings.Join(ss, ""))
}

// MustWriteString to buffer
func (b *Buffer) MustWriteString(ss ...string) {
_, err := b.WriteString(strings.Join(ss, ""))
if err != nil {
panic(err)
}
}

// ResetAndGet buffer string.
func (b *Buffer) ResetAndGet() string {
s := b.String()
b.Reset()
return s
}

// ByteChanPool struct
//
// Usage:
Expand All @@ -72,57 +20,9 @@ func (b *Buffer) ResetAndGet() string {
// buf:=bp.Get()
// defer bp.Put(buf)
// // use buf do something ...
//
// refer https://www.flysnow.org/2020/08/21/golang-chan-byte-pool.html
// from https://github.com/minio/minio/blob/master/internal/bpool/bpool.go
type ByteChanPool struct {
c chan []byte
w int
wcap int
}
type ByteChanPool = byteutil.ChanPool

// NewByteChanPool instance
func NewByteChanPool(maxSize int, width int, capWidth int) *ByteChanPool {
return &ByteChanPool{
c: make(chan []byte, maxSize),
w: width,
wcap: capWidth,
}
}

// Get gets a []byte from the BytePool, or creates a new one if none are
// available in the pool.
func (bp *ByteChanPool) Get() (b []byte) {
select {
case b = <-bp.c:
// reuse existing buffer
default:
// create new buffer
if bp.wcap > 0 {
b = make([]byte, bp.w, bp.wcap)
} else {
b = make([]byte, bp.w)
}
}
return
}

// Put returns the given Buffer to the BytePool.
func (bp *ByteChanPool) Put(b []byte) {
select {
case bp.c <- b:
// buffer went back into pool
default:
// buffer didn't go back into pool, just discard
}
}

// Width returns the width of the byte arrays in this pool.
func (bp *ByteChanPool) Width() (n int) {
return bp.w
}

// WidthCap returns the cap width of the byte arrays in this pool.
func (bp *ByteChanPool) WidthCap() (n int) {
return bp.wcap
func NewByteChanPool(maxSize, width, capWidth int) *ByteChanPool {
return byteutil.NewChanPool(maxSize, width, capWidth)
}
54 changes: 54 additions & 0 deletions strutil/crypto.go
@@ -0,0 +1,54 @@
package strutil

import (
"crypto/hmac"
"crypto/md5"
"crypto/sha256"
"encoding/hex"
"fmt"
)

// Md5 Generate a 32-bit md5 string
func Md5(src any) string {
return hex.EncodeToString(Md5Bytes(src))
}

// MD5 Generate a 32-bit md5 string
func MD5(src any) string { return Md5(src) }

// GenMd5 Generate a 32-bit md5 string
func GenMd5(src any) string { return Md5(src) }

// Md5Bytes Generate a 32-bit md5 bytes
func Md5Bytes(src any) []byte {
h := md5.New()
if s, ok := src.(string); ok {
h.Write([]byte(s))
} else {
h.Write([]byte(fmt.Sprint(src)))
}
return h.Sum(nil)
}

// HashPasswd for quick hash an input password string
func HashPasswd(pwd, key string) string {
hm := hmac.New(sha256.New, []byte(key))
hm.Write([]byte(pwd))

return hex.EncodeToString(hm.Sum(nil))
}

// VerifyPasswd for quick verify input password is valid
//
// - pwdMAC from db or config, generated by EncryptPasswd()
func VerifyPasswd(pwdMAC, pwd, key string) bool {
decBts, err := hex.DecodeString(pwdMAC)
if err != nil {
return false
}

hm := hmac.New(sha256.New, []byte(key))
hm.Write([]byte(pwd))

return hmac.Equal(decBts, hm.Sum(nil))
}
26 changes: 26 additions & 0 deletions strutil/crypto_test.go
@@ -0,0 +1,26 @@
package strutil_test

import (
"testing"

"github.com/gookit/goutil/dump"
"github.com/gookit/goutil/strutil"
"github.com/gookit/goutil/testutil/assert"
)

func TestMd5(t *testing.T) {
assert.Eq(t, "e10adc3949ba59abbe56e057f20f883e", strutil.Md5("123456"))
assert.Eq(t, "e10adc3949ba59abbe56e057f20f883e", strutil.MD5("123456"))
assert.Eq(t, "a906449d5769fa7361d7ecc6aa3f6d28", strutil.GenMd5("123abc"))
assert.Eq(t, "289dff07669d7a23de0ef88d2f7129e7", strutil.GenMd5(234))
}

func TestEncryptPasswd(t *testing.T) {
key := "ot54c"
pwd := "abc123456"

msgMac := strutil.HashPasswd(pwd, key)
dump.P(msgMac)
assert.NotEmpty(t, msgMac)
assert.True(t, strutil.VerifyPasswd(msgMac, pwd, key))
}
25 changes: 0 additions & 25 deletions strutil/encode.go
Expand Up @@ -2,11 +2,8 @@ package strutil

import (
"bytes"
"crypto/md5"
"encoding/base32"
"encoding/base64"
"encoding/hex"
"fmt"
"net/url"
"strings"
"text/template"
Expand Down Expand Up @@ -73,28 +70,6 @@ func StripSlashes(s string) string {
// -------------------- encode --------------------
//

// Md5 Generate a 32-bit md5 string
func Md5(src any) string {
return hex.EncodeToString(Md5Bytes(src))
}

// MD5 Generate a 32-bit md5 string
func MD5(src any) string { return Md5(src) }

// GenMd5 Generate a 32-bit md5 string
func GenMd5(src any) string { return Md5(src) }

// Md5Bytes Generate a 32-bit md5 bytes
func Md5Bytes(src any) []byte {
h := md5.New()
if s, ok := src.(string); ok {
h.Write([]byte(s))
} else {
h.Write([]byte(fmt.Sprint(src)))
}
return h.Sum(nil)
}

// URLEncode encode url string.
func URLEncode(s string) string {
if pos := strings.IndexRune(s, '?'); pos > -1 { // escape query data
Expand Down
7 changes: 0 additions & 7 deletions strutil/encode_test.go
Expand Up @@ -7,13 +7,6 @@ import (
"github.com/gookit/goutil/testutil/assert"
)

func TestMd5(t *testing.T) {
assert.Eq(t, "e10adc3949ba59abbe56e057f20f883e", strutil.Md5("123456"))
assert.Eq(t, "e10adc3949ba59abbe56e057f20f883e", strutil.MD5("123456"))
assert.Eq(t, "a906449d5769fa7361d7ecc6aa3f6d28", strutil.GenMd5("123abc"))
assert.Eq(t, "289dff07669d7a23de0ef88d2f7129e7", strutil.GenMd5(234))
}

func TestEscape(t *testing.T) {
tests := struct{ give, want string }{
"<p>some text</p>",
Expand Down

0 comments on commit 8eef351

Please sign in to comment.