使用Go的base64.StdEncoding.Decode()方法:如何选择目标字节片的大小?

我想使用Decodehttps://golang.org/pkg/encoding/base64/#Encoding.Decode)来解码一段字节,并且想知道,给定这个方法签名,

func (enc *Encoding) Decode(dst, src []byte) (n int, err error)

如何选择dst字节切片的大小,使其足够大以捕获输出。例如,此代码片段(改编自https://golang.org/pkg/encoding/base64/#Encoding.DecodeString

package main


import (

    "encoding/base64"

    "fmt"

)


func main() {

    str := "c29tZSBkYXRhIHdpdGggACBhbmQg77u/"

    dst := make([]byte, 1024)

    _, err := base64.StdEncoding.Decode(dst, []byte(str))

    if err != nil {

        fmt.Println("error:", err)

        return

    }

    fmt.Printf("%s\n", dst)

}

印刷


some data with  and 

但是,如果我选择的尺寸dst太小(例如0),我会感到index out of range恐慌:


panic: runtime error: index out of range


goroutine 1 [running]:

encoding/base64.(*Encoding).decodeQuantum(0xc000084000, 0x1193018, 0x0, 0x0, 0xc000080f30, 0x20, 0x20, 0x4, 0x10, 0x10, ...)

    /usr/local/Cellar/go@1.12/1.12.12/libexec/src/encoding/base64/base64.go:352 +0x567

encoding/base64.(*Encoding).Decode(0xc000084000, 0x1193018, 0x0, 0x0, 0xc000080f30, 0x20, 0x20, 0xc000080f38, 0x105779d, 0x10b16e0)

    /usr/local/Cellar/go@1.12/1.12.12/libexec/src/encoding/base64/base64.go:500 +0x5aa

main.main()

    /Users/kurt/Documents/Scratch/base64_decode.go:11 +0xb4

exit status 2

如何dst根据 的大小选择 的大小src以可靠地解码输入?


肥皂起泡泡
浏览 148回答 2
2回答

忽然笑

您应该使用它base64.DecodedLen来查找解码输入所需的最大大小,然后使用n返回的值Decode来找出它实际写入该切片的时间。

侃侃无极

由于输入以 8 位字节编码,但输出以 6 位(radix-64)字节编码,因此输出需要是输入大小的 8/6 = 4/3 倍。所以这应该有效:package mainimport (    "encoding/base64"    "fmt")func main() {    str := "c29tZSBkYXRhIHdpdGggACBhbmQg77u/"    dst := make([]byte, len(str)*len(str)/base64.StdEncoding.DecodedLen(len(str)))    _, err := base64.StdEncoding.Decode(dst, []byte(str))    if err != nil {        fmt.Println("error:", err)        return    }    fmt.Printf("%s\n", dst)}基于其中的实现,DecodedLen()一般情况下返回输入长度的3/4倍:// DecodedLen returns the maximum length in bytes of the decoded data// corresponding to n bytes of base64-encoded data.func (enc *Encoding) DecodedLen(n int) int {    if enc.padChar == NoPadding {        // Unpadded data may end with partial block of 2-3 characters.        return n * 6 / 8    }    // Padded base64 should always be a multiple of 4 characters in length.    return n / 4 * 3}但最后,我最终只是将输入转换为字符串并使用,DecodeString()因为它已经体现了这个逻辑。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go