diff --git a/langext/base62.go b/langext/base62.go new file mode 100644 index 0000000..811de81 --- /dev/null +++ b/langext/base62.go @@ -0,0 +1,74 @@ +package langext + +import ( + "crypto/rand" + "errors" + "math" + "math/big" + "strings" +) + +var ( + base62Base = uint64(62) + base62CharacterSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +) + +func RandBase62(rlen int) string { + bi52 := big.NewInt(int64(len(base62CharacterSet))) + + randMax := big.NewInt(math.MaxInt64) + + r := "" + + for i := 0; i < rlen; i++ { + v, err := rand.Int(rand.Reader, randMax) + if err != nil { + panic(err) + } + + r += string(base62CharacterSet[v.Mod(v, bi52).Int64()]) + } + + return r +} + +func EncodeBase62(num uint64) string { + if num == 0 { + return "0" + } + + b := make([]byte, 0) + + // loop as long the num is bigger than zero + for num > 0 { + r := num % base62Base + + num -= r + num /= base62Base + + b = append([]byte{base62CharacterSet[int(r)]}, b...) + } + + return string(b) +} + +func DecodeBase62(str string) (uint64, error) { + if str == "" { + return 0, errors.New("empty string") + } + + result := uint64(0) + + for _, v := range str { + result *= base62Base + + pos := strings.IndexRune(base62CharacterSet, v) + if pos == -1 { + return 0, errors.New("invalid character: " + string(v)) + } + + result += uint64(pos) + } + + return result, nil +} diff --git a/langext/rand.go b/langext/rand.go index f934abe..9c841cf 100644 --- a/langext/rand.go +++ b/langext/rand.go @@ -3,8 +3,6 @@ package langext import ( "crypto/rand" "io" - "math" - "math/big" ) func RandBytes(size int) []byte { @@ -15,24 +13,3 @@ func RandBytes(size int) []byte { } return b } - -func RandBase62(rlen int) string { - ecs := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" - - bi52 := big.NewInt(int64(len(ecs))) - - randMax := big.NewInt(math.MaxInt64) - - r := "" - - for i := 0; i < rlen; i++ { - v, err := rand.Int(rand.Reader, randMax) - if err != nil { - panic(err) - } - - r += string(ecs[v.Mod(v, bi52).Int64()]) - } - - return r -}