微博mid与字符串id互转golang实现

版本一

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
}

添加新评论