Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "fmt"
- "math"
- "reflect"
- "runtime"
- "sort"
- "time"
- )
- // 62^i | i = 1..10
- var limits = [10]uint64{62, 3844, 238328, 14776336, 916132832, 56800235584, 3521614606208, 218340105584896, 13537086546263552, 839299365868340200}
- const abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
- func b62Encode(n uint64) string {
- const Log62 = 4.127134385045091555346396446
- l := 1
- if n > 0 {
- l = 1 + int(math.Log(float64(n))/Log62)
- }
- result := make([]byte, l)
- for i := l - 1; i >= 0; i-- {
- result[i] = abc[n%62]
- n = n / 62
- }
- return string(result)
- }
- func b62Encode2(n uint64) string {
- var l int
- var v uint64
- for l, v = range limits {
- if n < v {
- break
- }
- }
- result := make([]byte, l+1)
- for i := l; i >= 0; i-- {
- result[i] = abc[n%62]
- n = n / 62
- }
- return string(result)
- }
- func b62Encode3(n uint64) string {
- l := sort.Search(len(limits), func(i int) bool { return limits[i] < n })
- result := make([]byte, l+1)
- for i := l; i >= 0; i-- {
- result[i] = abc[n%62]
- n = n / 62
- }
- return string(result)
- }
- func b62Encode4(n uint64) string {
- l, k := 0, len(limits)
- for l < k {
- h := l + (k-l)/2
- if limits[h] > n {
- l = h + 1
- } else {
- k = h
- }
- }
- result := make([]byte, l+1)
- for i := l; i >= 0; i-- {
- result[i] = abc[n%62]
- n = n / 62
- }
- return string(result)
- }
- func b62Encode5(n uint64) string {
- result := make([]byte, 0)
- for n > 0 {
- result = append([]byte{abc[n%62]}, result...)
- n = n / 62
- }
- return string(result)
- }
- func b62Encode6(n uint64) string {
- result := make([]byte, 11)
- i := 10
- for {
- result[i] = abc[n%62]
- n = n / 62
- if n == 0 {
- break
- }
- i--
- }
- return string(result[i:])
- }
- func b62Decode(a string) (uint64, error) {
- if len(a) == 0 {
- return 0, fmt.Errorf("base62 string must not be empty")
- }
- var v uint64
- for i := 0; i < len(a); i++ {
- c := int(a[i])
- p := 0
- switch {
- case int('a') <= c && c <= int('z'):
- p = c - int('a')
- case int('A') <= c && c <= int('Z'):
- p = c - int('A') + 26
- case int('0') <= c && c <= int('9'):
- p = c - int('0') + 52
- default:
- return 0, fmt.Errorf("invalid base62 symbol: '%c'", a[i])
- }
- v *= 62
- v += uint64(p)
- }
- return v, nil
- }
- type b26encoder func(uint64) string
- func test(fn b26encoder) {
- const N = 10000000
- t0 := time.Now()
- for i := uint64(0); i < N; i++ {
- b62 := fn(i)
- r, _ := b62Decode(b62)
- if r != i {
- fmt.Printf("%v != %v\n", r, i)
- return
- }
- }
- fmt.Printf("%v: %v\n", runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name(), time.Since(t0))
- }
- func main() {
- test(b62Encode)
- test(b62Encode2)
- test(b62Encode3)
- test(b62Encode4)
- test(b62Encode5)
- test(b62Encode6)
- }
Add Comment
Please, Sign In to add comment