代码之家  ›  专栏  ›  技术社区  ›  aronchick

Base64解组过程中的缓冲区大小是否使其过大?

go
  •  0
  • aronchick  · 技术社区  · 2 年前

    我试图将字节数组编码为Base64,但遇到了两个问题。我可以用 base64.StdEncoding.EncodedLen(text) 但我担心这很昂贵,所以我想看看我是否可以用 len(text) 。以下是代码(这些函数被命名为“Marshal”,因为我在JSON封送过程中将它们用作字段转换器):

    package main
    
    import (
        "crypto/rand"
        "encoding/base64"
        "fmt"
    )
    
    func main() {
        b := make([]byte, 60)
        _, _ = rand.Read(b)
    
        // Marshal Create Dst Buffer
        MarshalTextBuffer(b)
    
        // Marshal Convert to String
        MarshalTextStringWithBufferLen(b)
    
        // Marshal Convert to String
        MarshalTextStringWithDecodedLen(b)
    }
    
    func MarshalTextBuffer(text []byte) error {
        ba := base64.StdEncoding.EncodeToString(text)
        fmt.Println(ba)
        return nil
    }
    
    func MarshalTextStringWithBufferLen(text []byte) error {
        ba := make([]byte, len(text)+30) // Why does len(text) not suffice? Temporarily using '30' for now, just so it doesn't overrun.
        base64.StdEncoding.Encode(ba, text)
        fmt.Println(ba)
        return nil
    }
    
    func MarshalTextStringWithDecodedLen(text []byte) error {
        ba := make([]byte, base64.StdEncoding.EncodedLen(len(text)))
        base64.StdEncoding.Encode(ba, text)
        fmt.Println(ba)
        return nil
    }
    
    

    以下是输出:

    IL5CW8T9WSgwU5Hyi9JsLLkU/EcydY6pG2fgLQJsMaXgxhSh74RTagzr6b9yDeZ8CP4Azc8xqq5/+Cgk
    [73 76 53 67 87 56 84 57 87 83 103 119 85 53 72 121 105 57 74 115 76 76 107 85 47 69 99 121 100 89 54 112 71 50 102 103 76 81 74 115 77 97 88 103 120 104 83 104 55 52 82 84 97 103 122 114 54 98 57 121 68 101 90 56 67 80 52 65 122 99 56 120 113 113 53 47 43 67 103 107 0 0 0 0 0 0 0 0 0 0]
    [73 76 53 67 87 56 84 57 87 83 103 119 85 53 72 121 105 57 74 115 76 76 107 85 47 69 99 121 100 89 54 112 71 50 102 103 76 81 74 115 77 97 88 103 120 104 83 104 55 52 82 84 97 103 122 114 54 98 57 121 68 101 90 56 67 80 52 65 122 99 56 120 113 113 53 47 43 67 103 107]
    

    为什么中间的那个 MarshalTextStringWithBufferLen 需要额外的填充?

    base64.StdEncoding.EncodedLen 一个昂贵的函数(例如,我可以用底部函数来解决它,但我担心成本)。

    0 回复  |  直到 2 年前
        1
  •  2
  •   Andrew W. Phillips    2 年前

    Base-64编码将二进制数据(每字节8位)存储为文本(每字节使用6位),因此每3个字节编码为4个字节(3x8=4x6)。所以 len(text) + 30 中的错误,应该是 len(text)*4/3 (如果len(text)可被3整除),但为了提高可读性和避免错误,您应该使用 base64.StdEncoding.EncodedLen() 以获取长度。

    如果您查看的代码 base64.StdEncoding.EncodedLen 你会发现它和你自己计算一样快(尤其是在划线时)。