BASE64編碼原理與Golang代碼調(diào)用

一.概念簡介

Base64是一種基于64個(gè)可打印字符來表示二進(jìn)制數(shù)據(jù)的表示方法。由于2^6=64,所以每6個(gè)比特為一個(gè)單元,對(duì)應(yīng)某個(gè)可打印字符。3個(gè)字節(jié)有24個(gè)比特,對(duì)應(yīng)于4個(gè)Base64單元,即3個(gè)字節(jié)可由4個(gè)可打印字符來表示。它可用來作為電子郵件的傳輸編碼。在Base64中的可打印字符包括字母A-Z、a-z、數(shù)字0-9,這樣共有62個(gè)字符,此外兩個(gè)可打印符號(hào)在不同的系統(tǒng)中而不同。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、虛擬主機(jī)、營銷軟件、網(wǎng)站建設(shè)、王屋網(wǎng)站維護(hù)、網(wǎng)站推廣。

Base64常用于在通常處理文本數(shù)據(jù)的場合,表示、傳輸、存儲(chǔ)一些二進(jìn)制數(shù)據(jù)

二.代碼調(diào)用

在Golang中提供了代碼庫可以供我們直接調(diào)用,用于實(shí)現(xiàn)Base64的編碼與解碼,其提供了對(duì)兩種格式的數(shù)據(jù)進(jìn)行編碼(與解碼)

const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"

來自golang源碼base64.go

1.標(biāo)準(zhǔn)數(shù)據(jù)(encodeStd)
    msg := "Mac"
    //編碼
    base64EncodedString := base64.StdEncoding.EncodeToString([]byte(msg))
    fmt.Println("Base64編碼后:", base64EncodedString)
    //解碼
    base64DecodedByte, err := base64.StdEncoding.DecodeString(base64EncodedString)
    if err != nil {
        log.Panic(err)
    }
    fmt.Println("Base64解碼后的字節(jié)數(shù)組:", base64DecodedByte)
    fmt.Println("Base64解碼后:", string(base64DecodedByte))

返回打印結(jié)果

Base64編碼后: TWFj
Base64解碼后的字節(jié)數(shù)組: [77 97 99]
Base64解碼后: Mac
2.URL數(shù)據(jù)(encodeURL)
msgUrl :="http://www.google.com"
    base64UrlEncodedString :=base64.URLEncoding.EncodeToString([]byte(msgUrl))
    fmt.Println("Base64編碼后:", base64UrlEncodedString)
    base64UrlDecodedByte,err := base64.URLEncoding.DecodeString(base64UrlEncodedString)
    if err !=nil {
        log.Panic(err)
    }
    fmt.Println("Base64解碼后的字節(jié)數(shù)組:", base64UrlDecodedByte)
    fmt.Println("Base64解碼后:", string(base64UrlDecodedByte))

返回打印結(jié)果

Base64編碼后: aHR0cDovL3d3dy5nb29nbGUuY29t
Base64解碼后的字節(jié)數(shù)組: [104 116 116 112 58 47 47 119 119 119 46 103 111 111 103 108 101 46 99 111 109]
Base64解碼后: http://www.google.com
三.編碼原理
1.將每個(gè)字符轉(zhuǎn)成ASCII編碼(10進(jìn)制)
fmt.Println([]byte(msg)) //[77 97 99]
2.將10進(jìn)制編碼轉(zhuǎn)成2進(jìn)制編碼
fmt.Printf("%b",[]byte(msg)) 
//[1001101 1100001 1100011] 

補(bǔ)齊8位為:

[01001101 01100001 01100011] 
3.將2進(jìn)制編碼按照6位一組進(jìn)行平分
010011 010110 000101 100011
4.轉(zhuǎn)成10進(jìn)制數(shù)

010011 ==> 1x2^0 + 1x2^1 + 0 + 0 + 1x2^4 = 19

010110 ==> 0 + 1x2^1 + 1x2^2 + 0 + 1x2^4 = 22

000101 ==> 1x2^0 + 0 + 1 x 2^2 + 0 + 0 + 0 = 5

100011 ==> 1x2^0 + 1x2^1 + 0 + 0 + 0 + 1x2^5 = 35

5.將十進(jìn)制數(shù)作為索引,從Base64編碼表中查找字符

BASE64編碼原理與Golang代碼調(diào)用

19 對(duì)應(yīng) T
22 對(duì)應(yīng) W
5  對(duì)應(yīng) F
35 對(duì)應(yīng) j (注意是小寫)

注意

  • 若文本為3個(gè)字符,則剛好編碼為4個(gè)字符長度(3 8 = 4 6)
  • 若文本為2個(gè)字符,則編碼為3個(gè)字符,尾部用一個(gè)"="補(bǔ)齊
  • 若文本為1個(gè)字符,則編碼為2個(gè)字符,尾部用兩個(gè)"="補(bǔ)齊
四.Base58代碼實(shí)現(xiàn)

Base58是用于Bitcoin中使用的一種獨(dú)特的編碼方式,主要用于產(chǎn)生Bitcoin的錢包地址。

相比Base64,Base58不使用數(shù)字"0",字母大寫"O",字母大寫"I",和字母小寫"l",以及"+"和"/"符號(hào)。

設(shè)計(jì)Base58主要的目的是:

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

但是這個(gè)base58的計(jì)算量比base64的計(jì)算量多了很多。因?yàn)?8不是2的整數(shù)倍,需要不斷用除法去計(jì)算。

而且長度也比base64稍微多了一點(diǎn)。

附上golang的代碼實(shí)現(xiàn)

package main

import (
    "math/big"
    "bytes"
    "fmt"
)

func main() {
    /*
    測試Base58
     */

    //1.原始數(shù)據(jù)
    data1 := []byte{10, 20, 30, 40, 50, 60}
    data1 = append([]byte{0},data1...) //前綴+數(shù)據(jù)
    fmt.Println("原始數(shù)據(jù):",data1)
    //Base58編碼
    encode:=Base58Encode(data1)
    fmt.Println("Base58編碼后:",encode) //[]byte
    fmt.Println(string(encode))
    //Base58解碼
    decode:=Base58Decode(encode)
    fmt.Println("Base58解碼后:",decode)

    //測試數(shù)據(jù)
    data2:="wangergou"
    encode2:=Base58Encode([]byte(data2))
    fmt.Println(encode2)
    fmt.Println(string(encode2))

    decode2:=Base58Decode(encode2)
    fmt.Println(decode2)
    fmt.Println(string(decode2))
    fmt.Println(string(decode2[1:])) //wangergou
}

//base64

/*
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
0(零),O(大寫的o),I(大寫的i),l(小寫的L),+,/
 */

var b58Alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")

//字節(jié)數(shù)組轉(zhuǎn)Base58,加密
func Base58Encode(input []byte) []byte {
    var result [] byte
    x := big.NewInt(0).SetBytes(input)
    //fmt.Println("x:",x)
    base := big.NewInt(int64(len(b58Alphabet)))//58
    //fmt.Println("base:",base)
    zero := big.NewInt(0)
    mod := &big.Int{}
    for x.Cmp(zero) != 0 {
        x.DivMod(x, base, mod)
        //fmt.Println("x:",x,",mod:",mod) //0-57
        result = append(result, b58Alphabet[mod.Int64()])
        //fmt.Println("result:",string(result))
    }
    //將得到result中的數(shù)據(jù)進(jìn)行反轉(zhuǎn)
    ReverseBytes(result)
    for b := range input { //遍歷input數(shù)組:index,value
        if b == 0x00 {
            result = append([]byte{b58Alphabet[0]}, result...)
        } else {
            break
        }
    }
    //1 result

    return result

}

//Base58轉(zhuǎn)字節(jié)數(shù)組,解密
func Base58Decode(input [] byte) []byte {
    result := big.NewInt(0)
    zeroBytes := 0
    for b := range input {
        if b == 0x00 {
            zeroBytes++
        }
    }
    fmt.Println("zeroBytes:",zeroBytes)
    payload := input[zeroBytes:]
    for _, b := range payload {
        charIndex := bytes.IndexByte(b58Alphabet, b)
        result.Mul(result, big.NewInt(58))
        result.Add(result, big.NewInt(int64(charIndex)))
    }

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

    return decoded
}

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

分享題目:BASE64編碼原理與Golang代碼調(diào)用
網(wǎng)站路徑:http://bm7419.com/article36/gijjpg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站設(shè)計(jì)、搜索引擎優(yōu)化、移動(dòng)網(wǎng)站建設(shè)用戶體驗(yàn)、網(wǎng)頁設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)