簡介
Base64是網絡上最常見的用于傳輸8Bit位元組代碼的編碼方式之一,可用于在HTTP環境下傳遞較長的辨別資訊。Go 的 encoding/base64 提供了對base64的編解碼操作。
encoding/base64 定義了一個Encoding結構體,表示Base64的編/解碼器。并且導出了四個常用的Encoding對象:StdEncoding、URLEncoding、RawStdEncoding、RawURLEncoding。StdEncoding表示标準的編/解碼器。URLEncoding用于對URL編解碼,編解碼過程中會将Base64編碼中的特殊标記+和/替換為-和_。RawStdEncoding和RawURLEncoding是StdEncoding和URLEncoding的非padding版本。主要API如下:
// 四個導出的編碼/解碼器
var StdEncoding = NewEncoding(encodeStd)
var URLEncoding = NewEncoding(encodeURL)
var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
var RawURLEncoding = URLEncoding.WithPadding(NoPadding)
// Encoding 結構體表示編碼/解碼器
type Encoding struct {
// ...
}
// Encoding提供了如下編解碼的方法
// 解碼,[]byte版本将src解碼為dest,傳回成功寫入的位元組數和錯誤
// string版本應用于字元串
func (enc *Encoding) Decode(dst, src []byte) (n int, err error)
func (enc *Encoding) DecodeString(s string) ([]byte, error)
// 編碼,[]byte版本将src編碼為dest
// string版本應用于字元串
func (enc *Encoding) Encode(dst, src []byte)
func (enc *Encoding) EncodeToString(src []byte) string
// 設定enc的padding,傳回Encoding指針,NoPadding表示不進行padding操作
func (enc Encoding) WithPadding(padding rune) *Encoding
// 另外 encoding/base64 還提供了流式操作的接口
func NewDecoder(enc *Encoding, r io.Reader) io.Reader
func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser
Encoding應用
下面的程式示範了 Encoding 的用法:
package main
import (
"encoding/base64"
"errors"
"fmt"
)
// 為了友善,聲明該函數,省去錯誤處理
func mustDecode(enc *base64.Encoding, str string) string {
data, err := enc.DecodeString(str)
if err != nil {
panic(err)
}
return string(data)
}
// 該函數測試編解碼
// enc為要測試的Encoding對象,str為要測試的字元串
func testEncoding(enc *base64.Encoding, str string) {
// 編碼
encStr := enc.EncodeToString([]byte(str))
fmt.Println(encStr)
// 解碼
decStr := mustDecode(enc, encStr)
if decStr != str { // 編碼後再解碼應該與原始字元串相同
// 這裡判斷如果不同,則panic
panic(errors.New("unequal!"))
}
}
func main() {
const testStr = "Go語言程式設計"
// 測試StdEncoding,注意列印結果裡的/為URL中的特殊字元,最後有一個padding
testEncoding(base64.StdEncoding, testStr) // 列印:R2/or63oqIDnvJbnqIs=
// 測試URLEncoding,可以看到/被替換為_
testEncoding(base64.URLEncoding, testStr) // 列印:R2_or63oqIDnvJbnqIs=
// 測試RawStdEncoding,可以看到去掉了padding
testEncoding(base64.RawStdEncoding, testStr) // 列印:R2/or63oqIDnvJbnqIs
// 測試RawURLEncoding,可以看到/被替換Wie_,并且卻掉了padding
testEncoding(base64.RawURLEncoding, testStr) // 列印:R2_or63oqIDnvJbnqIs
}
流式API的應用
流式API多用于在資料傳輸過程中對資料進行Base64編碼或解碼。比如在讀取較大檔案時,或者網絡傳輸時。下面的程式讀取testfile中的資料,利用base64編碼後儲存到testfile_enc:
package main
import (
"encoding/base64"
"io"
"log"
"os"
)
type Buf struct {
data []byte
size int
}
func main() {
f, err := os.Open("E:\\testfile")
if err != nil {
log.Fatalln(err)
}
defer f.Close()
fEnc, err := os.Create("E:\\testfile_enc")
if err != nil {
log.Fatalln(err)
}
defer fEnc.Close()
w := base64.NewEncoder(base64.StdEncoding, fEnc)
io.Copy(w, f)
w.Close()
}