-
Notifications
You must be signed in to change notification settings - Fork 191
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ feat: encodx - add sub package, add some files from strutil pkg
- Loading branch information
Showing
9 changed files
with
323 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package encodx | ||
|
||
import ( | ||
"encoding/base32" | ||
"encoding/base64" | ||
) | ||
|
||
// BaseEncoder interface | ||
type BaseEncoder interface { | ||
Encode(dst []byte, src []byte) | ||
EncodeToString(src []byte) string | ||
Decode(dst []byte, src []byte) (n int, err error) | ||
DecodeString(s string) ([]byte, error) | ||
} | ||
|
||
// | ||
// -------------------- base encode -------------------- | ||
// | ||
|
||
// base32 encoding with no padding | ||
var ( | ||
B32Std = base32.StdEncoding.WithPadding(base32.NoPadding) | ||
B32Hex = base32.HexEncoding.WithPadding(base32.NoPadding) | ||
) | ||
|
||
// B32Encode base32 encode | ||
func B32Encode(str string) string { | ||
return B32Std.EncodeToString([]byte(str)) | ||
} | ||
|
||
// B32Decode base32 decode | ||
func B32Decode(str string) string { | ||
dec, _ := B32Std.DecodeString(str) | ||
return string(dec) | ||
} | ||
|
||
// base64 encoding with no padding | ||
var ( | ||
B64Std = base64.StdEncoding.WithPadding(base64.NoPadding) | ||
B64URL = base64.URLEncoding.WithPadding(base64.NoPadding) | ||
) | ||
|
||
// B64Encode base64 encode | ||
func B64Encode(str string) string { | ||
return B64Std.EncodeToString([]byte(str)) | ||
} | ||
|
||
// B64EncodeBytes base64 encode | ||
func B64EncodeBytes(src []byte) []byte { | ||
buf := make([]byte, B64Std.EncodedLen(len(src))) | ||
B64Std.Encode(buf, src) | ||
return buf | ||
} | ||
|
||
// B64Decode base64 decode | ||
func B64Decode(str string) string { | ||
dec, _ := B64Std.DecodeString(str) | ||
return string(dec) | ||
} | ||
|
||
// B64DecodeBytes base64 decode | ||
func B64DecodeBytes(str []byte) []byte { | ||
dbuf := make([]byte, B64Std.DecodedLen(len(str))) | ||
n, _ := B64Std.Decode(dbuf, str) | ||
return dbuf[:n] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package encodx_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/gookit/goutil/encodx" | ||
"github.com/gookit/goutil/testutil/assert" | ||
) | ||
|
||
func TestBaseDecode(t *testing.T) { | ||
is := assert.New(t) | ||
|
||
is.Eq("GEZGCYTD", encodx.B32Encode("12abc")) | ||
is.Eq("12abc", encodx.B32Decode("GEZGCYTD")) | ||
|
||
// b23 hex | ||
is.Eq("64P62OJ3", encodx.B32Hex.EncodeToString([]byte("12abc"))) | ||
// fmt.Println(time.Now().Format("20060102150405")) | ||
dateStr := "20230908101122" | ||
is.Eq("68O34CPG74O3GC9G64OJ4CG", encodx.B32Hex.EncodeToString([]byte(dateStr))) | ||
|
||
is.Eq("YWJj", encodx.B64Encode("abc")) | ||
is.Eq("abc", encodx.B64Decode("YWJj")) | ||
|
||
is.Eq([]byte("YWJj"), encodx.B64EncodeBytes([]byte("abc"))) | ||
is.Eq([]byte("abc"), encodx.B64DecodeBytes([]byte("YWJj"))) | ||
|
||
is.Eq("MTJhYmM", encodx.B64URL.EncodeToString([]byte("12abc"))) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package hashutil | ||
|
||
import ( | ||
"crypto/md5" | ||
"crypto/sha1" | ||
"crypto/sha256" | ||
"crypto/sha512" | ||
"encoding/hex" | ||
"fmt" | ||
"hash" | ||
"hash/crc32" | ||
"hash/crc64" | ||
"strings" | ||
|
||
"github.com/gookit/goutil/encodx" | ||
) | ||
|
||
// hash algorithm names | ||
const ( | ||
AlgoCRC32 = "crc32" | ||
AlgoCRC64 = "crc64" | ||
AlgoMD5 = "md5" | ||
AlgoSHA1 = "sha1" | ||
AlgoSHA224 = "sha224" | ||
AlgoSHA256 = "sha256" | ||
AlgoSHA384 = "sha384" | ||
AlgoSHA512 = "sha512" | ||
) | ||
|
||
// MD5 generate md5 string by given src | ||
func MD5(src any) string { | ||
return string(HexBytes(AlgoMD5, src)) | ||
} | ||
|
||
// ShortMD5 Generate a 16-bit md5 bytes. | ||
// remove first 8 and last 8 bytes from 32-bit md5. | ||
func ShortMD5(src any) string { | ||
return string(HexBytes(AlgoMD5, src)[8:24]) | ||
} | ||
|
||
// Hash generate hex hash string by given algorithm | ||
func Hash(algo string, src any) string { | ||
return string(HexBytes(algo, src)) | ||
} | ||
|
||
// HexBytes generate hex hash bytes by given algorithm | ||
func HexBytes(algo string, src any) []byte { | ||
bs := HashSum(algo, src) | ||
dst := make([]byte, hex.EncodedLen(len(bs))) | ||
hex.Encode(dst, bs) | ||
return dst | ||
} | ||
|
||
// Hash32 generate hash by given algorithm, then use base32 encode. | ||
func Hash32(algo string, src any) string { | ||
return string(Base32Bytes(algo, src)) | ||
} | ||
|
||
// Base32Bytes generate base32 hash bytes by given algorithm | ||
func Base32Bytes(algo string, src any) []byte { | ||
bs := HashSum(algo, src) | ||
dst := make([]byte, encodx.B32Hex.EncodedLen(len(bs))) | ||
encodx.B32Hex.Encode(dst, bs) | ||
return dst | ||
} | ||
|
||
// Hash64 generate hash by given algorithm, then use base64 encode. | ||
func Hash64(algo string, src any) string { | ||
return string(Base64Bytes(algo, src)) | ||
} | ||
|
||
// Base64Bytes generate base64 hash bytes by given algorithm | ||
func Base64Bytes(algo string, src any) []byte { | ||
bs := HashSum(algo, src) | ||
dst := make([]byte, encodx.B64Std.EncodedLen(len(bs))) | ||
encodx.B64Std.Encode(dst, bs) | ||
return dst | ||
} | ||
|
||
// HashSum generate hash sum bytes by given algorithm | ||
func HashSum(algo string, src any) []byte { | ||
hh := NewHash(algo) | ||
switch val := src.(type) { | ||
case []byte: | ||
hh.Write(val) | ||
case string: | ||
hh.Write([]byte(val)) | ||
default: | ||
hh.Write([]byte(fmt.Sprint(src))) | ||
} | ||
return hh.Sum(nil) | ||
} | ||
|
||
// NewHash create hash.Hash instance | ||
// | ||
// algo: crc32, crc64, md5, sha1, sha224, sha256, sha384, sha512, sha512_224, sha512_256 | ||
func NewHash(algo string) hash.Hash { | ||
switch strings.ToLower(algo) { | ||
case AlgoCRC32: | ||
return crc32.NewIEEE() | ||
case AlgoCRC64: | ||
return crc64.New(crc64.MakeTable(crc64.ISO)) | ||
case AlgoMD5: | ||
return md5.New() | ||
case AlgoSHA1: | ||
return sha1.New() | ||
case AlgoSHA224: | ||
return sha256.New224() | ||
case AlgoSHA256: | ||
return sha256.New() | ||
case AlgoSHA384: | ||
return sha512.New384() | ||
case AlgoSHA512: | ||
return sha512.New() | ||
case "sha512_224": | ||
return sha512.New512_224() | ||
case "sha512_256": | ||
return sha512.New512_256() | ||
default: | ||
panic("invalid hash algorithm:" + algo) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package hashutil_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/gookit/goutil/encodx/hashutil" | ||
"github.com/gookit/goutil/testutil/assert" | ||
) | ||
|
||
func TestHash(t *testing.T) { | ||
tests := []struct { | ||
src any | ||
algo string | ||
want string | ||
}{ | ||
{"abc12", "crc32", "b744b523"}, | ||
{"abc12", "crc64", "41b31776c4200000"}, | ||
{"abc12", "md5", "b2157e7b2ae716a747597717f1efb7a0"}, | ||
{"abc12", "sha1", "8fe670fef2b8c74ef8987cdfccdb32e96ad4f9a2"}, | ||
} | ||
|
||
for _, tt := range tests { | ||
assert.Equal(t, tt.want, hashutil.Hash(tt.algo, tt.src)) | ||
} | ||
|
||
assert.Panics(t, func() { | ||
hashutil.Hash("unknown", nil) | ||
}) | ||
} | ||
|
||
func TestHash32(t *testing.T) { | ||
tests := []struct { | ||
src any | ||
algo string | ||
want string | ||
}{ | ||
{"abc12", "crc32", "MT2BA8O"}, | ||
{"abc12", "crc64", "86PHETM440000"}, | ||
{"abc12", "md5", "M8ANSUPASSBAEHQPESBV3RTNK0"}, | ||
{"abc12", "sha1", "HVJ71VNIN33KTU4OFJFSPMPIT5LD9UD2"}, | ||
} | ||
|
||
for _, tt := range tests { | ||
assert.Equal(t, tt.want, hashutil.Hash32(tt.algo, tt.src)) | ||
} | ||
} | ||
|
||
func TestHash64(t *testing.T) { | ||
tests := []struct { | ||
src any | ||
algo string | ||
want string | ||
}{ | ||
{"abc12", "crc32", "t0S1Iw"}, | ||
{"abc12", "crc64", "QbMXdsQgAAA"}, | ||
{"abc12", "md5", "shV+eyrnFqdHWXcX8e+3oA"}, | ||
{"abc12", "sha1", "j+Zw/vK4x074mHzfzNsy6WrU+aI"}, | ||
} | ||
|
||
for _, tt := range tests { | ||
assert.Equal(t, tt.want, hashutil.Hash64(tt.algo, tt.src)) | ||
} | ||
} | ||
|
||
func TestMd5(t *testing.T) { | ||
assert.NotEmpty(t, hashutil.MD5("abc")) | ||
assert.NotEmpty(t, hashutil.MD5([]int{12, 34})) | ||
|
||
assert.Eq(t, "202cb962ac59075b964b07152d234b70", hashutil.MD5("123")) | ||
assert.Eq(t, "900150983cd24fb0d6963f7d28e17f72", hashutil.MD5("abc")) | ||
|
||
// short md5 | ||
assert.Eq(t, "ac59075b964b0715", hashutil.ShortMD5("123")) | ||
assert.Eq(t, "3cd24fb0d6963f7d", hashutil.ShortMD5("abc")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package hashutil | ||
|
||
import ( | ||
"crypto/hmac" | ||
"crypto/sha256" | ||
"encoding/hex" | ||
) | ||
|
||
// HashPasswd for quick hash an input password string, use sha256. | ||
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 | ||
// | ||
// - wantPwd from db or config, generated by EncryptPasswd() | ||
func VerifyPasswd(wantPwd, pwd, key string) bool { | ||
decBts, err := hex.DecodeString(wantPwd) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
hm := hmac.New(sha256.New, []byte(key)) | ||
hm.Write([]byte(pwd)) | ||
|
||
return hmac.Equal(decBts, hm.Sum(nil)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package hashutil_test |
File renamed without changes.
File renamed without changes.
File renamed without changes.