亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

根據 RFC2045 限制行長度的 Base64 編碼

根據 RFC2045 限制行長度的 Base64 編碼

Go
侃侃爾雅 2023-07-17 17:45:46
RFC2045 第 6.8 節規定 Base64 輸出的最大編碼行長度應為 76 個字符或更少。Golang 流編寫器base64.NewEncoder沒有任何行分割選項,如此處所示。package mainimport (    "encoding/base64"    "io"    "os"    "strings")// See https://www.ietf.org/rfc/rfc2045.txt, section 6.8 for notes on maximum line length of 76 charactersfunc main() {    data := "It is only the hairs on a gooseberry that prevent it from being a grape! This is long enough to need a line split"    rdr := strings.NewReader(data)    wrt := base64.NewEncoder(base64.StdEncoding, os.Stdout)    io.Copy(wrt, rdr)}輸出是SXQgaXMgb25seSB0aGUgaGFpcnMgb24gYSBnb29zZWJlcnJ5IHRoYXQgcHJldmVudCBpdCBmcm9tIGJlaW5nIGEgZ3JhcGUhIEl0IGlzIG9ubHkgdGhlIGhhaXJzIG9uIGEgZ29vc2ViZXJyeSB0aGF0IHByZXZlbnQgaXQgZnJvbSBiZWluZyBhIGdyYXBl是否有基于流的分割線解決方案?MIME庫僅提供基于字符串的編碼選項。
查看完整描述

1 回答

?
夢里花落0921

TA貢獻1772條經驗 獲得超6個贊

這是我嘗試創建一個簡單的Writer. 它考慮到不同數量的輸入數據,具有可配置的塊長度和分隔符序列。它使用字節片寫入塊,這有望提高效率。


package main


import (

    "encoding/base64"

    "io"

    "os"

    "strings"

)


func min(a, b int) int {

    if a < b {

        return a

    }

    return b

}


type linesplitter struct {

    len   int

    count int

    sep   []byte

    w     io.Writer

}


// NewWriter that splits input every len bytes with a sep byte sequence, outputting to writer w

func (ls *linesplitter) NewWriter(len int, sep []byte, w io.Writer) io.WriteCloser {

    return &linesplitter{len: len, count: 0, sep: sep, w: w}

}


// Split a line in to ls.len chunks with separator

func (ls *linesplitter) Write(in []byte) (n int, err error) {

    writtenThisCall := 0

    readPos := 0

    // Leading chunk size is limited by: how much input there is; defined split length; and

    // any residual from last time

    chunkSize := min(len(in), ls.len-ls.count)

    // Pass on chunk(s)

    for {

        ls.w.Write(in[readPos:(readPos + chunkSize)])

        readPos += chunkSize // Skip forward ready for next chunk

        ls.count += chunkSize

        writtenThisCall += chunkSize


        // if we have completed a chunk, emit a separator

        if ls.count >= ls.len {

            ls.w.Write(ls.sep)

            writtenThisCall += len(ls.sep)

            ls.count = 0

        }

        inToGo := len(in) - readPos

        if inToGo <= 0 {

            break // reached end of input data

        }

        // Determine size of the NEXT chunk

        chunkSize = min(inToGo, ls.len)

    }

    return writtenThisCall, nil

}


func (ls *linesplitter) Close() (err error) {

    return nil

}


// See https://www.ietf.org/rfc/rfc2045.txt, section 6.8 for notes on maximum line length of 76 characters

func main() {

    data := "It is only the hairs on a gooseberry that prevent it from being a grape! This is long enough to need a line split"

    shortData := "hello there"


    var ls linesplitter

    lsWriter := ls.NewWriter(76, []byte("\r\n"), os.Stdout)

    wrt := base64.NewEncoder(base64.StdEncoding, lsWriter)


    for i := 0; i < 10; i++ {

        io.Copy(wrt, strings.NewReader(shortData))

        io.Copy(wrt, strings.NewReader(data))

        io.Copy(wrt, strings.NewReader(shortData))

    }

}

...歡迎提出意見/改進。


查看完整回答
反對 回復 2023-07-17
  • 1 回答
  • 0 關注
  • 291 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號