版本一
package main
import (
"fmt"
"strconv"
"strings"
"math"
)
const EMETA = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" //48-57 97-122 65-90
const META_LENGTH = 62
var DMETA = map[string]int{"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "a": 10, "b": 11, "c": 12, "d": 13, "e": 14, "f": 15, "g": 16, "h": 17, "i": 18, "j": 19, "k": 20, "l": 21, "m": 22, "n": 23, "o": 24, "p": 25, "q": 26, "r": 27, "s": 28, "t": 29, "u": 30, "v": 31, "w": 32, "x": 33, "y": 34, "z": 35, "A": 36, "B": 37, "C": 38, "D": 39, "E": 40, "F": 41, "G": 42, "H": 43, "I": 44, "J": 45, "K": 46, "L": 47, "M": 48, "N": 49, "O": 50, "P": 51, "Q": 52, "R": 53, "S": 54, "T": 55, "U": 56, "V": 57, "W": 58, "X": 59, "Y": 60, "Z": 61}
func main() {
fmt.Println(EncodeId(4587500141552212))
fmt.Println(DecodeStr("JAIhg6vNG"))
}
func EncodeId(id int) string {
str := ""
for {
round := id / 10e6
remain := id % 10e6
id = round
tmpStr := I2S(remain)
if round == 0 {
str += tmpStr
break
}
for s := 4 - len(tmpStr); s > 0; s-- {
str += "0"
}
str += tmpStr
}
return rev(str)
}
func I2S(num int) string {
if num == 0 {
return "0"
}
result := []byte{}
for num > 0 {
round := num / META_LENGTH
remain := num % META_LENGTH
result = append(result, EMETA[remain])
num = round
}
return string(result)
}
func S2I(str string) int {
str = strings.TrimSpace(str)
length := len(str)
result := 0
for index, char := range []byte(str) {
result += DMETA[string(char)] * int(math.Pow(META_LENGTH, float64(length-index-1)))
}
return result
}
func DecodeStr(str string) int {
length := len(str)
round := length / 4
if round == 0 {
return S2I(str)
}
newStr := ""
remain := length % 4
if remain != 0 {
newStr += strconv.Itoa(S2I(str[0:remain]))
}
for i := remain; i < length; i += 4 {
newStr += strconv.Itoa(S2I(str[i : i+4]))
}
result, _ := strconv.Atoi(newStr)
return result
}
func rev(str string) string {
result := []rune(str)
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
result[i], result[j] = result[j], result[i]
}
return string(result)
}
版本二
优化了62进制数学计算,去掉了const定义和map 字符串常量 硬编码,转为ASCII码直接计算
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
fmt.Println(EncodeId(4587500141552212))
fmt.Println(DecodeStr("JAIhg6vNG"))
}
func EncodeId(id int) string {
str := ""
for {
round := id / 10e6
remain := id % 10e6
id = round
tmpStr := I2S(remain)
if round == 0 {
str += tmpStr
break
}
for s := 4 - len(tmpStr); s > 0; s-- {
str += "0"
}
str += tmpStr
}
return rev(str)
}
func I2S(num int) string {
if num == 0 {
return "0"
}
result := []byte{}
for num > 0 {
round := num / 62
remain := num % 62
result = append(result, idx2byte(remain))
num = round
}
return string(result)
}
func S2I(str string) int {
str = strings.TrimSpace(str)
result := 0
for _, char := range str {
result = result*62 + idx(char)
}
return result
}
func DecodeStr(str string) int {
length := len(str)
round := length / 4
if round == 0 {
return S2I(str)
}
newStr := ""
remain := length % 4
if remain != 0 {
newStr += strconv.Itoa(S2I(str[0:remain]))
}
for i := remain; i < length; i += 4 {
newStr += strconv.Itoa(S2I(str[i : i+4]))
}
result, _ := strconv.Atoi(newStr)
return result
}
func rev(str string) string {
result := []rune(str)
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
result[i], result[j] = result[j], result[i]
}
return string(result)
}
func idx(c rune) int {
i := int(c)
if i >= 48 && i <= 57 {
return i - 48
}
if c >= 97 && c <= 122 {
return i - 97 + 10
}
return i - 65 + 36
}
func idx2byte(idx int) byte {
if idx >= 0 && idx < 10 {
return byte(idx + 48) //48
}
if idx >= 10 && idx < 36 {
return byte(idx + 87) //97 - 10
}
return byte(idx + 29) // 65 - 36
}
版本三,去掉了所有标准库东西,转为纯数学计算
package main
import (
"fmt"
)
func main() {
fmt.Println(EncodeId(4587500141552212))
fmt.Println(DecodeStr("JAIhg6vNG"))
}
func EncodeId(id int) string {
str := ""
for {
round := id / 10e6
remain := id % 10e6
id = round
tmpStr := I2S(remain)
if round == 0 {
str += tmpStr
break
}
for s := 4 - len(tmpStr); s > 0; s-- {
str += "0"
}
str += tmpStr
}
return rev(str)
}
func I2S(num int) string {
if num == 0 {
return "0"
}
result := []byte{}
for num > 0 {
result = append(result, idx2byte(num%62))
num = num / 62
}
return string(result)
}
func S2I(str string) int {
//str = strings.TrimSpace(str)
result := 0
for _, char := range str {
result = result*62 + idx(char)
}
return result
}
func DecodeStr(str string) int {
length := len(str)
round := length / 4
if round == 0 {
return S2I(str)
}
remain := length % 4
result := 0
if remain != 0 {
tmp := S2I(str[0:remain])
for i := round * 7; i > 0; i-- {
tmp = tmp * 10
}
result += tmp
}
for round > 0 {
round--
tmp := S2I(str[length-(round+1)*4+remain-1 : length-round*4+remain-1])
for i := round * 7; i > 0; i-- {
tmp = tmp * 10
}
result += tmp
}
return result
}
func rev(str string) string {
result := []rune(str)
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
result[i], result[j] = result[j], result[i]
}
return string(result)
}
func idx(c rune) int {
i := int(c)
if i >= 48 && i <= 57 {
return i - 48
}
if c >= 97 && c <= 122 {
return i - 97 + 10
}
return i - 65 + 36
}
func idx2byte(idx int) byte {
if idx >= 0 && idx < 10 {
return byte(idx + 48) //48
}
if idx >= 10 && idx < 36 {
return byte(idx + 87) //97 - 10
}
return byte(idx + 29) // 65 - 36
}
陈诛掎:文章真不错https://www.iqdyx.cn/news/51.html