内容简介:Base58是用于Bitcoin中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+“和”/"符号。设计Base58主要的目的是:避免混淆。在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。
base58
Base58是用于Bitcoin中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+“和”/"符号。
设计Base58主要的目的是:
避免混淆。在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。
不使用"+“和”/"的原因是非字母或数字的字符串作为帐号较难被接受。
没有标点符号,通常不会被从中间分行。
大部分的软件支持双击选择整个字符串。
base58编码
package main import ( "math/big" "fmt" ) //切片存储base58字母 var b58Alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") func Base58Encode(input []byte) []byte{ //定义一个字节切片,返回值 var result []byte //把字节数组input转化为了大整数big.Int x:= big.NewInt(0).SetBytes(input) //长度58的大整数 base := big.NewInt(int64(len(b58Alphabet))) //0的大整数 zero := big.NewInt(0) //大整数的指针 mod := &big.Int{} //循环,不停地对x取余数,大小为58 for x.Cmp(zero) != 0 { x.DivMod(x,base,mod) // 对x取余数 //讲余数添加到数组当中 result = append(result, b58Alphabet[mod.Int64()]) } //反转字节数组 ReverseBytes(result) //如果这个字节数组的前面为字节0,会把它替换为1. for _,b:=range input{ if b ==0x00{ result = append([]byte{b58Alphabet[0]},result...) }else{ break } } return result } //反转字节数组 func ReverseBytes(data []byte){ for i,j :=0,len(data) - 1;i<j;i,j = i+1,j - 1{ data[i],data[j] = data[j],data[i] } } //测试 反转操作 func main(){ org := []byte("qwerty") fmt.Println(string(org)) ReverseBytes(org) fmt.Println(string(org)) //测试编码 fmt.Printf("%s",string( Base58Encode([]byte("hello jonson")))) }
解码
func Base58Decode(input []byte) []byte{ result := big.NewInt(0) zeroBytes :=0 for _,b :=range input{ if b=='1'{ zeroBytes++ }else{ break } } payload:= input[zeroBytes:] for _,b := range payload{ charIndex := bytes.IndexByte(b58Alphabet,b) //反推出余数 result.Mul(result,big.NewInt(58)) //之前的结果乘以58 result.Add(result,big.NewInt(int64(charIndex))) //加上这个余数 } decoded :=result.Bytes() decoded = append(bytes.Repeat([]byte{0x00},zeroBytes),decoded...) return decoded }
完整代码
package main import ( "math/big" "fmt" "bytes" ) 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) // 对x取余数 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=='1'{ zeroBytes++ }else{ break } } payload:= input[zeroBytes:] for _,b := range payload{ charIndex := bytes.IndexByte(b58Alphabet,b) //反推出余数 result.Mul(result,big.NewInt(58)) //之前的结果乘以58 result.Add(result,big.NewInt(int64(charIndex))) //加上这个余数 } decoded :=result.Bytes() decoded = append(bytes.Repeat([]byte{0x00},zeroBytes),decoded...) return decoded } func ReverseBytes(data []byte){ for i,j :=0,len(data) - 1;i<j;i,j = i+1,j - 1{ data[i],data[j] = data[j],data[i] } } func main(){ org := []byte("qwerty") fmt.Println(string(org)) ReverseBytes(org) fmt.Println(string(org)) fmt.Printf("%s\n",string( Base58Encode([]byte("hello jonson")))) fmt.Printf("%s",string(Base58Decode([]byte("2yGEbwRFyav6CimZ7")))) }
参考资料
(比特币wiki-base58编码)[ https://en.bitcoin.it/wiki/Base58Check_encoding#Version_bytes ]
(维基百科-base58编码)[ https://zh.wikipedia.org/wiki/Base58 ]
-
本文链接: https://dreamerjonson.com/2018/12/05/golang-32-base58/
-
版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 区块链技术+区块链怎么赚钱?
- 区块链技术入门:区块链是什么
- 阿里申请可“行政干预”区块链专利,区块链变味?
- 中国区块链商学院:区块链基础知识
- 从Java到区块链:如何成为区块链开发人员
- 通过python构建一个区块链来学习区块链
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。