Guest User

Untitled

a guest
Jan 16th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.60 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "math"
  6. "reflect"
  7. "runtime"
  8. "sort"
  9. "time"
  10. )
  11.  
  12. // 62^i | i = 1..10
  13. var limits = [10]uint64{62, 3844, 238328, 14776336, 916132832, 56800235584, 3521614606208, 218340105584896, 13537086546263552, 839299365868340200}
  14.  
  15. const abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  16.  
  17. func b62Encode(n uint64) string {
  18. const Log62 = 4.127134385045091555346396446
  19. l := 1
  20. if n > 0 {
  21. l = 1 + int(math.Log(float64(n))/Log62)
  22. }
  23. result := make([]byte, l)
  24. for i := l - 1; i >= 0; i-- {
  25. result[i] = abc[n%62]
  26. n = n / 62
  27. }
  28. return string(result)
  29. }
  30.  
  31. func b62Encode2(n uint64) string {
  32. var l int
  33. var v uint64
  34. for l, v = range limits {
  35. if n < v {
  36. break
  37. }
  38. }
  39. result := make([]byte, l+1)
  40. for i := l; i >= 0; i-- {
  41. result[i] = abc[n%62]
  42. n = n / 62
  43. }
  44. return string(result)
  45. }
  46.  
  47. func b62Encode3(n uint64) string {
  48. l := sort.Search(len(limits), func(i int) bool { return limits[i] < n })
  49. result := make([]byte, l+1)
  50. for i := l; i >= 0; i-- {
  51. result[i] = abc[n%62]
  52. n = n / 62
  53. }
  54. return string(result)
  55. }
  56.  
  57. func b62Encode4(n uint64) string {
  58. l, k := 0, len(limits)
  59. for l < k {
  60. h := l + (k-l)/2
  61. if limits[h] > n {
  62. l = h + 1
  63. } else {
  64. k = h
  65. }
  66. }
  67. result := make([]byte, l+1)
  68. for i := l; i >= 0; i-- {
  69. result[i] = abc[n%62]
  70. n = n / 62
  71. }
  72. return string(result)
  73. }
  74.  
  75. func b62Encode5(n uint64) string {
  76. result := make([]byte, 0)
  77. for n > 0 {
  78. result = append([]byte{abc[n%62]}, result...)
  79. n = n / 62
  80. }
  81. return string(result)
  82. }
  83.  
  84. func b62Encode6(n uint64) string {
  85. result := make([]byte, 11)
  86. i := 10
  87. for {
  88. result[i] = abc[n%62]
  89. n = n / 62
  90. if n == 0 {
  91. break
  92. }
  93. i--
  94. }
  95. return string(result[i:])
  96. }
  97.  
  98. func b62Decode(a string) (uint64, error) {
  99. if len(a) == 0 {
  100. return 0, fmt.Errorf("base62 string must not be empty")
  101. }
  102. var v uint64
  103. for i := 0; i < len(a); i++ {
  104. c := int(a[i])
  105. p := 0
  106. switch {
  107. case int('a') <= c && c <= int('z'):
  108. p = c - int('a')
  109. case int('A') <= c && c <= int('Z'):
  110. p = c - int('A') + 26
  111. case int('0') <= c && c <= int('9'):
  112. p = c - int('0') + 52
  113. default:
  114. return 0, fmt.Errorf("invalid base62 symbol: '%c'", a[i])
  115. }
  116. v *= 62
  117. v += uint64(p)
  118. }
  119. return v, nil
  120. }
  121.  
  122. type b26encoder func(uint64) string
  123.  
  124. func test(fn b26encoder) {
  125. const N = 10000000
  126. t0 := time.Now()
  127. for i := uint64(0); i < N; i++ {
  128. b62 := fn(i)
  129. r, _ := b62Decode(b62)
  130. if r != i {
  131. fmt.Printf("%v != %v\n", r, i)
  132. return
  133. }
  134. }
  135. fmt.Printf("%v: %v\n", runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name(), time.Since(t0))
  136. }
  137.  
  138. func main() {
  139. test(b62Encode)
  140. test(b62Encode2)
  141. test(b62Encode3)
  142. test(b62Encode4)
  143. test(b62Encode5)
  144. test(b62Encode6)
  145. }
Add Comment
Please, Sign In to add comment