NO IMAGE

base58和base64一樣是一種二進位制轉可視字串的演算法,主要用來轉換大整數值。區別是,轉換出來的字串,去除了幾個看起來會產生歧義的字元,如 0 (零), O (大寫字母O), I (大寫的字母i) and l (小寫的字母L) ,和幾個影響雙擊選擇的字元,如/, 。

結果字符集正好58個字元(包括9個數字,24個大寫字母,25個小寫字母)。

編碼流程 (本質為大數與字串的轉化)

  1. 輸入為bytes,比如:[0x00, 0xFF]

  2. 忽略前面的0x00得到數字256

  3. 256通過base58編碼為字串”5Q”,因為要處理0x00,所以得到字串”15Q”

  4. 把字串“15Q”轉化為bytes: [0x49, 0x53, 0x81]

實現

package main
import (
"bytes"
"math/big"
)
var b58Alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
func Base58Encode(input []byte) []byte {
var result []byte
x := big.NewInt(0).SetBytes(input)
base := big.NewInt(int64(len(b58Alphabet)))
zero := big.NewInt(0)
mod := &big.Int{}
for x.Cmp(zero) != 0 {
x.DivMod(x, base, mod)
result = append(result, b58Alphabet[mod.Int64()])
}
ReverseBytes(result)
for _, b := range input {
if b == 0x00 {
result = append([]byte{b58Alphabet[0]}, result...)
} else {
break
}
}
return result
}
func Base58Decode(input []byte) []byte {
result := big.NewInt(0)
zeroBytes := 0
for _, b := range input {
if b != b58Alphabet[0] {
break
}
zeroBytes  
}
payload := input[zeroBytes:]
for _, b := range payload {
charIndex := bytes.IndexByte(b58Alphabet, b)
result.Mul(result, big.NewInt(int64(len(b58Alphabet))))
result.Add(result, big.NewInt(int64(charIndex)))
}
decoded := result.Bytes()
decoded = append(bytes.Repeat([]byte{byte(0x00)}, zeroBytes), decoded...)
return decoded
}

更多