2018|Base58编码解码Go实现

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. 【2018|Base58编码解码Go实现】把字符串“15Q”转化为bytes: [0x49, 0x53, 0x81]
实现
package mainimport ( "bytes" "math/big" )var b58Alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")func Base58Encode(input []byte) []byte { var result []bytex := 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 := 0for _, 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 }

更多

    推荐阅读