Skip to content

Commit

Permalink
👔 up: strutil - update some rand func logic, use custom rand instance
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Sep 1, 2023
1 parent 983446a commit 3e711a4
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 58 deletions.
80 changes: 36 additions & 44 deletions strutil/random.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package strutil

import (
"encoding/base64"
mathRand "math/rand"
mRand "math/rand"
"time"

"github.com/gookit/goutil/byteutil"
Expand All @@ -11,78 +10,55 @@ import (
// some consts string chars
const (
Numbers = "0123456789"
HexChars = "0123456789abcdef"
HexChars = "0123456789abcdef" // base16

AlphaBet = "abcdefghijklmnopqrstuvwxyz"
AlphaBet1 = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"

AlphaNum = "abcdefghijklmnopqrstuvwxyz0123456789"
AlphaNum2 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
AlphaNum3 = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"

Base62Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
Base64Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/"
)

// RandomChars generate give length random chars at `a-z`
func RandomChars(ln int) string {
cs := make([]byte, ln)
// UnixNano: 1607400451937462000
rn := mRand.New(mRand.NewSource(time.Now().UnixNano()))

for i := 0; i < ln; i++ {
// 1607400451937462000
mathRand.Seed(time.Now().UnixNano())
idx := mathRand.Intn(25) // 0 - 25
cs[i] = AlphaBet[idx]
// rand in 0 - 25
cs[i] = AlphaBet[rn.Intn(25)]
}

return string(cs)
}

// RandomCharsV2 generate give length random chars in `0-9a-z`
func RandomCharsV2(ln int) string {
cs := make([]byte, ln)
// UnixNano: 1607400451937462000
rn := mRand.New(mRand.NewSource(time.Now().UnixNano()))

for i := 0; i < ln; i++ {
// 1607400451937462000
mathRand.Seed(time.Now().UnixNano())
idx := mathRand.Intn(35) // 0 - 35
cs[i] = AlphaNum[idx]
// rand in 0 - 35
cs[i] = AlphaNum[rn.Intn(35)]
}

return string(cs)
}

// RandomCharsV3 generate give length random chars in `0-9a-zA-Z`
func RandomCharsV3(ln int) string {
cs := make([]byte, ln)
// UnixNano: 1607400451937462000
rn := mRand.New(mRand.NewSource(time.Now().UnixNano()))

for i := 0; i < ln; i++ {
// 1607400451937462000
mathRand.Seed(time.Now().UnixNano())
idx := mathRand.Intn(61) // 0 - 61
cs[i] = AlphaNum2[idx]
// rand in 0 - 61
cs[i] = AlphaNum2[rn.Intn(61)]
}

return string(cs)
}

// RandomBytes generate
func RandomBytes(length int) ([]byte, error) {
return byteutil.Random(length)
}

// RandomString generate.
//
// Example:
//
// // this will give us a 44 byte, base64 encoded output
// token, err := RandomString(32)
// if err != nil {
// // Serve an appropriately vague error to the
// // user, but log the details internally.
// }
func RandomString(length int) (string, error) {
b, err := RandomBytes(length)
return base64.URLEncoding.EncodeToString(b), err
}

// RandWithTpl generate random string with give template
func RandWithTpl(n int, letters string) string {
if len(letters) == 0 {
Expand All @@ -92,10 +68,26 @@ func RandWithTpl(n int, letters string) string {
ln := len(letters)
cs := make([]byte, n)
for i := 0; i < n; i++ {
mathRand.Seed(int64(time.Now().Nanosecond()))
idx := mathRand.Intn(ln)
cs[i] = letters[idx]
rn := mRand.New(mRand.NewSource(time.Now().UnixNano()))
// rand in 0 - ln
cs[i] = letters[rn.Intn(ln)]
}

return byteutil.String(cs)
}

// RandomString generate.
//
// Example:
//
// // this will give us a 44 byte, base64 encoded output
// token, err := RandomString(16) // eg: "I7S4yFZddRMxQoudLZZ-eg"
func RandomString(length int) (string, error) {
b, err := RandomBytes(length)
return B64URL.EncodeToString(b), err
}

// RandomBytes generate
func RandomBytes(length int) ([]byte, error) {
return byteutil.Random(length)
}
58 changes: 44 additions & 14 deletions strutil/random_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package strutil_test

import (
"encoding/base64"
"encoding/hex"
"fmt"
"math/rand"
Expand All @@ -16,54 +15,85 @@ func TestRandomChars(t *testing.T) {
for i := 0; i < 10; i++ {
str := strutil.RandomChars(4)
fmt.Println(str)

assert.Len(t, str, 4)
}
}

func TestRandomCharsV2(t *testing.T) {
keyMp := make(map[string]bool)
for i := 0; i < 10; i++ {
str := strutil.RandomCharsV2(4)
str := strutil.RandomCharsV2(6)
fmt.Println(str)
assert.Len(t, str, 6)
keyMp[str] = true
}
assert.Len(t, keyMp, 10)
}

assert.Len(t, str, 4)
// https://github.com/gookit/goutil/issues/121
func TestRandomCharsV2_issues121(t *testing.T) {
keyMp := make(map[string]bool)

for i := 0; i < 10; i++ {
str := strutil.RandomCharsV2(32)
fmt.Println(str)
assert.Len(t, str, 32)
keyMp[str] = true
}

assert.Len(t, keyMp, 10)
}

func TestRandomCharsV3(t *testing.T) {
for i := 0; i < 10; i++ {
size := 10
keyMp := make(map[string]bool)

for i := 0; i < size; i++ {
str := strutil.RandomCharsV3(4)
fmt.Println(str)
assert.Len(t, str, 4)
keyMp[str] = true
}
assert.Len(t, keyMp, size)
}

func TestRandWithTpl(t *testing.T) {
size := 10
keyMp := make(map[string]bool)

for i := 0; i < size; i++ {
str := strutil.RandWithTpl(4, strutil.AlphaBet1)
fmt.Println(str)
assert.Len(t, str, 4)
keyMp[str] = true
}
assert.Len(t, keyMp, size)

assert.NotEmpty(t, strutil.RandWithTpl(8, ""))
assert.NotEmpty(t, strutil.RandWithTpl(8, strutil.AlphaBet1))
}

func TestRandomBytes(t *testing.T) {
b, err := strutil.RandomBytes(3)

// 1607400451937462000
tsn := time.Now().UnixNano()
rand.Seed(tsn)
rn := rand.New(rand.NewSource(tsn))

fmt.Println(tsn)
fmt.Println(rand.Intn(12))
fmt.Println(rand.Intn(12))
fmt.Println(rn.Intn(12), rn.Intn(12))

fmt.Println(string(b))
fmt.Println(base64.URLEncoding.EncodeToString(b))
fmt.Println(base64.StdEncoding.EncodeToString(b))
fmt.Println(strutil.B64Std.EncodeToString(b))
fmt.Println(strutil.B64URL.EncodeToString(b))
fmt.Println(hex.EncodeToString(b))
assert.NoErr(t, err)
}

func TestRandomString(t *testing.T) {
s, err := strutil.RandomString(3)
s, err := strutil.RandomString(16)

fmt.Println(s)
assert.NoErr(t, err)
assert.True(t, len(s) > 3)

assert.NotEmpty(t, strutil.RandWithTpl(8, ""))
assert.NotEmpty(t, strutil.RandWithTpl(8, strutil.AlphaBet))
}

0 comments on commit 3e711a4

Please sign in to comment.