63 lines
1.1 KiB
Go
63 lines
1.1 KiB
Go
package generation
|
|
|
|
import (
|
|
"errors"
|
|
)
|
|
|
|
const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
|
|
|
var (
|
|
base = len(alphabet)
|
|
rev [256]int
|
|
)
|
|
|
|
func init() {
|
|
for i := range rev {
|
|
rev[i] = -1
|
|
}
|
|
for i, c := range alphabet {
|
|
rev[c] = i
|
|
}
|
|
}
|
|
|
|
// EncodeBase62 encodes a byte slice into a base62 string
|
|
func EncodeBase62(b []byte) string {
|
|
var n uint64
|
|
for i := 0; i < len(b); i++ {
|
|
n = n<<8 + uint64(b[i])
|
|
}
|
|
|
|
if n == 0 {
|
|
return string(alphabet[0])
|
|
}
|
|
|
|
var s []byte
|
|
for n > 0 {
|
|
r := n % uint64(base)
|
|
s = append([]byte{alphabet[r]}, s...)
|
|
n = n / uint64(base)
|
|
}
|
|
return string(s)
|
|
}
|
|
|
|
// DecodeBase62 decodes a base62 string into a byte slice
|
|
func DecodeBase62(s string) ([]byte, error) {
|
|
var n uint64
|
|
for i := 0; i < len(s); i++ {
|
|
c := s[i]
|
|
val := rev[c]
|
|
if val == -1 {
|
|
return nil, errors.New("invalid base62 character")
|
|
}
|
|
n = n*uint64(base) + uint64(val)
|
|
}
|
|
|
|
// Recover byte slice from integer
|
|
b := make([]byte, rawIDLength)
|
|
for i := rawIDLength - 1; i >= 0; i-- {
|
|
b[i] = byte(n & 0xff)
|
|
n >>= 8
|
|
}
|
|
return b, nil
|
|
}
|