github.com/chain5j/chain5j-pkg@v1.0.7/crypto/base/base36/base36.go (about) 1 // Package base36 2 // 3 // @author: xwc1125 4 package base36 5 6 import ( 7 "math" 8 "math/big" 9 "strings" 10 ) 11 12 var ( 13 base36 = []byte{ 14 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 15 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 16 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 17 'U', 'V', 'W', 'X', 'Y', 'Z'} 18 base36Lower = []byte{ 19 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 20 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 21 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 22 'u', 'v', 'w', 'x', 'y', 'z'} 23 24 index = map[byte]int{ 25 '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, 26 '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 27 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 28 'F': 15, 'G': 16, 'H': 17, 'I': 18, 'J': 19, 29 'K': 20, 'L': 21, 'M': 22, 'N': 23, 'O': 24, 30 'P': 25, 'Q': 26, 'R': 27, 'S': 28, 'T': 29, 31 'U': 30, 'V': 31, 'W': 32, 'X': 33, 'Y': 34, 32 'Z': 35, 33 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 34 'f': 15, 'g': 16, 'h': 17, 'i': 18, 'j': 19, 35 'k': 20, 'l': 21, 'm': 22, 'n': 23, 'o': 24, 36 'p': 25, 'q': 26, 'r': 27, 's': 28, 't': 29, 37 'u': 30, 'v': 31, 'w': 32, 'x': 33, 'y': 34, 38 'z': 35, 39 } 40 ) 41 42 // Encode encodes a number to base36. 43 func Encode(value uint64) string { 44 var res [16]byte 45 var i int 46 for i = len(res) - 1; ; i-- { 47 res[i] = base36[value%36] 48 value /= 36 49 if value == 0 { 50 break 51 } 52 } 53 54 return string(res[i:]) 55 } 56 57 // Decode decodes a base36-encoded string. 58 func Decode(s string) uint64 { 59 res := uint64(0) 60 l := len(s) - 1 61 for idx := range s { 62 c := s[l-idx] 63 res += uint64(index[c]) * uint64(math.Pow(36, float64(idx))) 64 } 65 return res 66 } 67 68 var bigRadix = big.NewInt(36) 69 var bigZero = big.NewInt(0) 70 71 // EncodeBytesAsBytes encodes a byte slice to base36. 72 func EncodeBytesAsBytes(b []byte) []byte { 73 x := new(big.Int) 74 x.SetBytes(b) 75 76 answer := make([]byte, 0, len(b)*136/100) 77 for x.Cmp(bigZero) > 0 { 78 mod := new(big.Int) 79 x.DivMod(x, bigRadix, mod) 80 answer = append(answer, base36[mod.Int64()]) 81 } 82 83 // leading zero bytes 84 for _, i := range b { 85 if i != 0 { 86 break 87 } 88 answer = append(answer, base36[0]) 89 } 90 91 // reverse 92 alen := len(answer) 93 for i := 0; i < alen/2; i++ { 94 answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i] 95 } 96 97 return answer 98 } 99 100 // EncodeBytes encodes a byte slice to base36 string. 101 func EncodeBytes(b []byte) string { 102 return string(EncodeBytesAsBytes(b)) 103 } 104 105 // DecodeToBytes decodes a base36 string to a byte slice, using alphabet. 106 func DecodeToBytes(isUpper bool, b string) []byte { 107 alphabet := string(base36) 108 if !isUpper { 109 alphabet = string(base36Lower) 110 } 111 answer := big.NewInt(0) 112 j := big.NewInt(1) 113 114 for i := len(b) - 1; i >= 0; i-- { 115 tmp := strings.IndexAny(alphabet, string(b[i])) 116 if tmp == -1 { 117 return []byte("") 118 } 119 idx := big.NewInt(int64(tmp)) 120 tmp1 := big.NewInt(0) 121 tmp1.Mul(j, idx) 122 123 answer.Add(answer, tmp1) 124 j.Mul(j, bigRadix) 125 } 126 127 tmpval := answer.Bytes() 128 129 var numZeros int 130 for numZeros = 0; numZeros < len(b); numZeros++ { 131 if b[numZeros] != alphabet[0] { 132 break 133 } 134 } 135 flen := numZeros + len(tmpval) 136 val := make([]byte, flen, flen) 137 copy(val[numZeros:], tmpval) 138 139 return val 140 }