为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
肥皂起泡泡 2023-08-14 14:42:27
我想使用Decode(https://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 mainimport (    "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 rangegoroutine 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 +0x567encoding/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 +0x5aamain.main()    /Users/kurt/Documents/Scratch/base64_decode.go:11 +0xb4exit status 2如何dst根据 的大小选择 的大小src以可靠地解码输入?
查看完整描述

2 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

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



查看完整回答
反对 回复 2023-08-14
?
侃侃无极

TA贡献2051条经验 获得超10个赞

由于输入以 8 位字节编码,但输出以 6 位(radix-64)字节编码,因此输出需要是输入大小的 8/6 = 4/3 倍。所以这应该有效:


package main


import (

    "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()因为它已经体现了这个逻辑。


查看完整回答
反对 回复 2023-08-14
  • 2 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信