參考:https://studygolang.com/pkgdoc
導入方式:
import "encoding/base64"
base64實現了RFC 4648規定的base64編碼。Base64是網絡上最常見的用於傳輸8Bit字節碼的編碼方式之一,Base64就是一種基於64個可打印字符(即6Bits)來表示二進制數據(即8Bits)的方法。Base64編碼是從二進制到字符的過程,可用於在HTTP環境下傳遞較長的標識信息,這樣更適合放在URL中進行傳遞。此時,采用Base64編碼具有不可讀性,需要解碼后才能閱讀。
該編碼的規則就是:
- 把3個字符變成4個字符:方法就是先將3個8Bits(3*8=24Bits)的值分成4個6Bits的值(4*6=24Bits),然后在這四個6Bits值前添加兩個0將其變為8Bits的值,這樣就能夠保證生成的4個值表示的值大小為(0~63),即可以將其轉成對應的ASCII碼(64個可打印字符)舉例:
轉換前: 01110011 00110001 00110011 拆分成4份: 011100 110011 000100 110011 高位補0: 00011100 00110011 00000100 00110011 對應的值為: 28 51 4 51 轉成對應的ASCII碼: c z E z
- 每76個字符加一個換行符
- 最后的結束符也要處理
type Encoding
type Encoding struct { // 內含隱藏或非導出字段 }
雙向的編碼/解碼協議,根據一個64字符的字符集定義,RFC 4648標准化了兩種字符集。默認字符集用於MIME(RFC 2045)和PEM(RFC 1421)編碼;另一種用於URL和文件名,用'-'和'_'替換了'+'和'/'。
func NewEncoding
func NewEncoding(encoder string) *Encoding
使用給出的字符集生成一個*Encoding,字符集必須是64字節的字符串。
Variables
var StdEncoding = NewEncoding(encodeStd)
RFC 4648定義的標准base64編碼字符集。
var URLEncoding = NewEncoding(encodeURL)
RFC 4648定義的另一base64編碼字符集,用於URL和文件名。
下面的兩個函數分別就是編碼和解碼的過程:
func (*Encoding) EncodeToString
func (enc *Encoding) EncodeToString(src []byte) string
返回將src編碼后的字符串。
func (*Encoding) DecodeString
func (enc *Encoding) DecodeString(s string) ([]byte, error)
返回base64編碼的字符串s代表的數據。
舉例:
package main
import(
"fmt"
"encoding/base64" ) func main() { msg := "Hello,world" //11個字符應該裝成15個base64編碼的字符 encoded := base64.StdEncoding.EncodeToString([]byte(msg)) fmt.Println(encoded) //SGVsbG8sd29ybGQ=,后面的=是作填充用的 decoded, err := base64.StdEncoding.DecodeString(encoded) if err != nil { fmt.Println("decode error:", err) return } fmt.Println(string(decoded))//Hello,world }
下面的方法不是將他們編碼成字符串:
解碼字符:
func (*Encoding) DecodedLen
func (enc *Encoding) DecodedLen(n int) int
返回n字節base64編碼的數據解碼后的最大長度。
func (*Encoding) Decode
func (enc *Encoding) Decode(dst, src []byte) (n int, err error)
將src的數據解碼后存入dst,最多寫DecodedLen(len(src))字節數據到dst,並返回寫入的字節數。 如果src包含非法字符,將返回成功寫入的字符數和CorruptInputError。換行符(\r、\n)會被忽略。
舉例:
package main import( "encoding/base64" "log" "fmt" "io" ) func main() { encoded := "Zm9vLGJhcg==" n := base64.StdEncoding.DecodedLen(len(encoded))//DecodedLen返回len(encoded)字節base64編碼的數據解碼后的最大長度 fmt.Println(n) //9 dbuf := make([]byte, n) _, err :=base64.StdEncoding.Decode(dbuf, []byte(encoded)) if err != nil && err != io.EOF { log.Fatal("Read failed", err) } fmt.Printf("decoded result : %s\n", dbuf) //decoded result : foo,bar }
下面兩個代碼組合進行編碼:
func (*Encoding) EncodedLen
func (enc *Encoding) EncodedLen(n int) int
返回n字節數據進行base64編碼后的最大長度。
func (*Encoding) Encode
func (enc *Encoding) Encode(dst, src []byte)
將src的數據編碼后存入dst,最多寫EncodedLen(len(src))字節數據到dst,並返回寫入的字節數。
函數會把輸出設置為4的倍數,因此不建議對大數據流的獨立數據塊執行此方法,使用NewEncoder()代替。
舉例:
package main import( "encoding/base64" "fmt" ) func main() { decoded := "foo,bar" n := base64.StdEncoding.EncodedLen(len(decoded))//DecodedLen返回len(encoded)字節base64編碼的數據解碼后的最大長度 fmt.Println(n) //12 dbuf := make([]byte, n) base64.StdEncoding.Encode(dbuf, []byte(decoded)) fmt.Printf("encode result : %s\n", dbuf) //encode result : Zm9vLGJhcg== }
下面就是生成編碼器和解碼器的方法,其實和上面的Encode和Decode實現的效果一樣,在編碼的是大數據流時使用下面的方法:
func NewEncoder(可寫Write)
func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser
創建一個新的base64流編碼器。寫入的數據會在編碼后再寫入w,base32編碼每3字節執行一次編碼操作;寫入完畢后,使用者必須調用Close方法以便將未寫入的數據從緩存中刷新到w中。
舉例:
package main import( "encoding/base64" "os" ) func main() { input := []byte("foo,bar") encoder := base64.NewEncoder(base64.StdEncoding, os.Stdout) //生成一個編碼器,會將調用Write()寫入的值編碼后寫到os.Stdout中 encoder.Write(input) encoder.Close() //返回Zm9vLGJhcg== }
func NewDecoder(可讀-Read)
func NewDecoder(enc *Encoding, r io.Reader) io.Reader
創建一個新的base64流解碼器。
舉例:
package main import( "encoding/base64" "strings" "log" "fmt" "io" ) func main() { encoded := "Zm9vLGJhcg==" decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encoded)) n := base64.StdEncoding.DecodedLen(len(encoded))//DecodedLen返回len(encoded)字節base64編碼的數據解碼后的最大長度 fmt.Println(n) //9 dbuf := make([]byte, n) _, err := decoder.Read(dbuf)//將讀取的解碼后的值寫到dbuf中 if err != nil && err != io.EOF { log.Fatal("Read failed", err) } fmt.Printf("decoded result : %s\n", dbuf) //decoded result : foo,bar }