1. 程式人生 > >golang[32]-區塊鏈-base58

golang[32]-區塊鏈-base58

base58

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

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

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{
//定義一個位元組切片,返回值
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"))))
}

解碼

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)  //反推出餘數

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
}

完整程式碼

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取餘數
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/

  • 版權宣告: 本部落格所有文章除特別宣告外,均採用 

    相關推薦

    golang[32]-區塊-base58

    base58 Base58是用於Bitcoin中使用的一種獨特的編碼方式,主要用於產生Bitcoin的錢包地址。相比Base64,Base58不使用數字"0",字母大寫"O",字母大寫"I",和字母小寫"l",以及"+“和”/"符號。 設計Base58主要的目的是:避免混淆。在某些字型下,數字0和字母

    golang[38]-區塊- 生成比特幣地址

    生成比特幣地址 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707

    golang[36]-區塊-資料簽名生成

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475

    golang[35]-區塊-私鑰公鑰生成

    1234567891011121314151617181920212223242526272829303132 //生成私鑰和公鑰func newKeyPair() (ecdsa.PrivateKey,[]byte){ //生成橢圓曲線,  secp256r1 曲

    golang[34]-區塊-對稱加密與非對稱加密

    對稱加密 對稱金鑰加密(英語:Symmetric-key algorithm)又稱為對稱加密、私鑰加密、共享金鑰加密,是密碼學中的一類加密演算法。這類演算法在加密和解密時使用相同的金鑰,或是使用兩個可以簡單地相互推算的金鑰。事實上,這組金鑰成為在兩個或多個成員間的共同祕密,以便維持專屬的通訊聯絡。與公開

    Golang實現區塊(一)—簡單區塊

    隨著比特幣、以太坊等虛擬貨幣的越來越火,作為這些虛擬貨幣背後支撐的區塊鏈技術,也被越來越多的人提及。下面我們將使用go語言對區塊鏈進行探討,並實現一個簡易的區塊鏈,本文暫不涉及poW、poS等共識演算法。 通過本文,你可以做到: 瞭解區塊 Hash演算法

    golang[42]-區塊-go實戰比特幣默克爾樹

    go實戰比特幣默克爾樹 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686

    golang[41]-區塊-默克爾樹構建

    大自然的啟示 Banyan樹的啟示:印度banyan樹,最大的一顆可以長到1萬平方米以上。其如此巨大的祕密就在於其枝幹也會產生根,起到支撐,從而作為附屬樹幹,繼續生成分支。大自然給人太多啟示…… Merkle Tree Merkle Tree,通常也被稱作Hash Tree,顧名思義,就是儲存has

    golang[40]-區塊-wif倒推出私鑰

    wif倒推出私鑰 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970

    <golang>簡單區塊的實現(帶POW挖礦系統)

    前言 在IT界,2018最火的熱詞相必就是區塊鏈了,C++和GO是目前最適合區塊鏈開發的兩種語言,所以咱們學GO的肯定得學一點區塊鏈的知識,但是區塊鏈涉及太多密碼學,金融學、p2p網路等知識了,從哪裡切入呢,今天我們就從用go實現一條帶有模擬挖礦系統的簡單區塊

    300行 Golang 實現區塊

    作者 瘋魔慕薇0x1 開篇  區塊鏈,時下最火的技術。前段時間一篇《A blockchain in 200 lines of code》更是在技術圈裡刷屏。在讀過 Lauri Hartikka 寫的這篇文章和程式碼後,我愈發對區塊鏈興趣濃厚。  紙上得來終覺淺,要深入瞭解一門

    golang 實現區塊系列二 | 工作量證明

    介紹在 上篇文章中, 我們構建了一個很簡單的資料結構,這個結構就是區塊鏈資料庫的本質。而且我們賦予了它們類似於鏈式操作中新增資料塊的能力:每個區塊和前一個區塊相連結。不過哦,我們的區塊鏈實現有一個很大的瑕疵:新增一個區塊太簡單了,成本太低了。區塊鏈和比特幣的其中一個重要基石則

    區塊,工作證明(POW)代碼+原理 golang版剖析

    區塊鏈 以太坊 工作證明 POW 實現機制 介紹在之前的文章中,我們構建了一個非常簡單的數據結構,這是塊鏈數據庫的本質。 而且我們可以用它們之間的鏈式關系向它添加區塊:每個區塊與前一個鏈接。 唉,然而在現實中添加一個區塊添加到鏈是艱巨的工作。工作證明塊鏈的一個關鍵思想是,必須通過工作證明才

    Golang區塊開發001-初始化區塊

    orm Once 返回 print Coding hash 進行 space tps 一. 代碼結構Block.go :定義區塊結構與方法BlockChain.go :定義區塊鏈結構與方法help.go :將常用代碼塊進行封裝,形成幫助庫main.go:測試代碼二.定義區塊

    Golang區塊開發002-初始化區塊與POW挖礦實現

    pow append var space [] sha2 測試結果 rep ring 目錄:一.初始化區塊鏈1.代碼結構2. 定義區塊結構與方法3. 定義區塊鏈結構與方法4. 幫助庫代碼5. 測試生成區塊與初始化區塊鏈6. 測試代碼二. POW挖礦實現1.代碼結構2. 定義

    golang區塊開發的視頻教程推薦

    視頻 info 之前 sts htm ola save part -h 目前網上關於golang區塊鏈開發的資源很少,以太坊智能合約相關的課程倒是很多,可能是由於前者的難度比後者難度大,課程開發需要投入更多精力。搜了一圈之後沒結果,我就直接去之前沒覆蓋的視頻網站找資源,包括

    【我的區塊之路】- golang原始碼分析之select的實現

    最近本人再找工作,恩,雖然本人使用go有2年左右了,但是其實還只是停留在語言使用的技巧位面,語言的很多底層實現機制還不是很清楚的,所以面試被問到很多底層,就很懵逼。這篇文章主要是自己對go學習的筆記。(本人還是一隻菜雞,各位海涵) 文章參考: 那麼se

    區塊社群開發者招募(Solidity/Golang/Java/Python/Swift/Kotlin)

    IOST歡迎社群開發者加入我們共同參與以下任務的開發: -IOST Chrome錢包外掛(優先) -IOST online IDE -智慧合約開發框架 -多語言SDK -文件翻譯 -硬體錢包 -Mac/PC版錢包 -iOS/Android版錢包 -DApp Demo和教程 開發者激勵

    【我的區塊之路】- golang原始碼分析之協程排程器底層實現( G、M、P)

    本人的原始碼是基於go 1.9.7 版本的哦! 緊接著之前寫的 【我的區塊鏈之路】- golang原始碼分析之select的底層實現 和 【我的區塊鏈之路】- golang原始碼分析之channel的底層實現 我們這一次需要對go的排程器做一番剖析。

    【我的區塊之路】- golang原始碼分析之channel的底層實現

    【轉載請標明出處】https://blog.csdn.net/qq_25870633/article/details/83388952 接上篇文章 【我的區塊鏈之路】- golang原始碼分析之select的底層實現 我這裡因為面試的時候也有被問到過 channel的底層實現