75 lines
1.2 KiB
Go
75 lines
1.2 KiB
Go
|
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
|
||
|
}
|