首页 > 解决方案 > 在 Go 中使用 base64.StdEncoding 或 base64.RawStdEncoding 解码 base64 字符串

问题描述

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

根据文档

const (
    StdPadding rune = '=' // Standard padding character
    NoPadding  rune = -1  // No padding
)

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

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

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

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

更新:

也许通过错误检查来做到这一点的一种原始方法如下

    rawByte, err := base64.StdEncoding.DecodeString(s)
    if err != nil {
        rawByte, err = base64.RawStdEncoding.DecodeString(s)
    }

标签: gobase64

解决方案


众所周知,在 go base64.StdEncoding 或 base64.RawStdEncoding 中有两种解码 base64 字符串的方法。

还有base64.URLEncoding使用字符-_替代 URL 不安全的 base64 字符+/.

我们是否应该通过检查填充的结尾是否为 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

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

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


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

rawByte, err := base64.StdEncoding.DecodeString(s)
if err != nil {
    rawByte, err = base64.RawStdEncoding.DecodeString(s)
}

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

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?
}

推荐阅读