溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

golang[32]-區(qū)塊鏈-base58

發(fā)布時間:2020-07-02 19:32:05 來源:網(wǎng)絡(luò) 閱讀:362 作者:jonson_jackson 欄目:開發(fā)技術(shù)

base58

Base58是用于Bitcoin中使用的一種獨(dú)特的編碼方式,主要用于產(chǎn)生Bitcoin的錢包地址。相比Base64,Base58不使用數(shù)字"0",字母大寫"O",字母大寫"I",和字母小寫"l",以及"+“和”/"符號。

設(shè)計Base58主要的目的是:
避免混淆。在某些字體下,數(shù)字0和字母大寫O,以及字母大寫I和字母小寫l會非常相似。
不使用"+“和”/"的原因是非字母或數(shù)字的字符串作為帳號較難被接受。
沒有標(biāo)點(diǎn)符號,通常不會被從中間分行。
大部分的軟件支持雙擊選擇整個字符串。

base58編碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package main

import (
"math/big"
"fmt"
)

//切片存儲base58字母
var b58Alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")


func Base58Encode(input []byte) []byte{
//定義一個字節(jié)切片,返回值
var result []byte

//把字節(jié)數(shù)組input轉(zhuǎn)化為了大整數(shù)big.Int
x:= big.NewInt(0).SetBytes(input)

//長度58的大整數(shù)
base := big.NewInt(int64(len(b58Alphabet)))
 //0的大整數(shù)
zero := big.NewInt(0)
//大整數(shù)的指針
mod := &big.Int{}

 //循環(huán),不停地對x取余數(shù),大小為58
for x.Cmp(zero) != 0 {
x.DivMod(x,base,mod)  // 對x取余數(shù)

   //講余數(shù)添加到數(shù)組當(dāng)中
result =  append(result, b58Alphabet[mod.Int64()])
}


//反轉(zhuǎn)字節(jié)數(shù)組
ReverseBytes(result)

//如果這個字節(jié)數(shù)組的前面為字節(jié)0,會把它替換為1.
for _,b:=range input{

if b ==0x00{
result =  append([]byte{b58Alphabet[0]},result...)
}else{
break
}
}


return result

}

//反轉(zhuǎn)字節(jié)數(shù)組
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]
}
}

//測試 反轉(zhuǎn)操作
func main(){
org := []byte("qwerty")
fmt.Println(string(org))

ReverseBytes(org)

fmt.Println(string(org))
//測試編碼
 fmt.Printf("%s",string( Base58Encode([]byte("hello jonson"))))
}

解碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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)  //反推出余數(shù)

result.Mul(result,big.NewInt(58))   //之前的結(jié)果乘以58

result.Add(result,big.NewInt(int64(charIndex)))  //加上這個余數(shù)

}

decoded :=result.Bytes()


decoded =  append(bytes.Repeat([]byte{0x00},zeroBytes),decoded...)
return decoded
}

完整代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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取余數(shù)
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)  //反推出余數(shù)

result.Mul(result,big.NewInt(58))   //之前的結(jié)果乘以58

result.Add(result,big.NewInt(int64(charIndex)))  //加上這個余數(shù)

}

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/

  • 版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 CC BY 4.0 CN協(xié)議 許可協(xié)議。轉(zhuǎn)載請注明出處!

golang[32]-區(qū)塊鏈-base58

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI