在Go中使用base64.StdEncoding或base64.RawStdEncoding解码base64字符串

zan*_*ngw 0 base64 go

我们知道,在 gobase64.StdEncodingbase64.RawStdEncoding. 如何正确使用其中之一来解码一个base64字符串?如果调用了不正确的编码方法。例如,如果RawStdEncoding使用 来解码一个字符串,就会出现StdEncoding错误。illegal base64 data at input byte xxx

每个文档

const (
    StdPadding rune = '=' // Standard padding character
    NoPadding  rune = -1  // No padding
)
Run Code Online (Sandbox Code Playgroud)

RawStdEncoding 是标准原始、未填充的 Base64 编码,如 RFC 4648 第 3.2 节中定义。这与 StdEncoding 相同,但省略了填充字符。

我们是否应该通过检查 padding 是否结束来区分它们StdPadding?代码片段

    lastByte := s[len(s)-1:]
    if lastByte == string(base64.StdPadding) {
        base64.StdEncoding.DecodeString(s)
    } else {
        base64.RawStdEncoding.DecodeString(s)
    }
Run Code Online (Sandbox Code Playgroud)

这是一种优雅的方式吗?或者我错过了什么?解码 Base64 字符串的优雅方法是什么?

更新:

也许是一种通过错误检查来完成此操作的原始方法,如下所示

    rawByte, err := base64.StdEncoding.DecodeString(s)
    if err != nil {
        rawByte, err = base64.RawStdEncoding.DecodeString(s)
    }
Run Code Online (Sandbox Code Playgroud)

col*_*tor 5

我们知道,在go中base64.StdEncoding或base64.RawStdEncoding有两种方法来解码base64字符串。

还有base64.URLEncoding,它使用字符-_作为 URL 不安全的 base64 字符+和 的替代品/

我们是否应该通过检查 padding 的结尾是否为 StdPadding 来区分它们?代码片段

这行不通。Base64 编码有三分之一的机会没有可见的填充:

b := []byte("abc123")  // len(b) % 3 == 0  - no padding

fmt.Println(base64.StdEncoding.EncodeToString(b))    // YWJjMTIz
fmt.Println(base64.RawStdEncoding.EncodeToString(b)) // YWJjMTIz
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/LMtIHlyXdn7

那么如何区分它们并确定使用了哪种编码呢?


是的,您可以像更新的问题一样进行双重解码:

rawByte, err := base64.StdEncoding.DecodeString(s)
if err != nil {
    rawByte, err = base64.RawStdEncoding.DecodeString(s)
}
Run Code Online (Sandbox Code Playgroud)

您可以使用一些技巧来做出一些有根据的猜测。例如:

e := base64.StdEncoding.EncodeToString(b) // always produces a mutiple of 4 length

if len(e) % 4 != 0 {
    // cannot be base64.StdEncoding - so try base64.RawStdEncoding?
}
Run Code Online (Sandbox Code Playgroud)