使用base64.解码或base64.RawStdEncoding解码base64字符串在Go &g



我们知道,在base64.StdEncodingbase64.RawStdEncoding中有两种解码base64字符串的方法。如何使用其中一个正确解码一个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)
}

我们知道,在围棋中有两种解码base64字符串的方法base64。

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

我们应该通过检查填充的结束来区分它们吗stdp加不加?代码片段

这行不通。有1/3的几率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?
}

如果您获得illegal base64 data at input byte ...则:

  • 您使用了错误的base64解码器,或者
  • 在调用解码器之前,base64字符串之后必须剥离更多数据,或者
  • 输入不是base64。

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

。就像你知道数据是base64编码的一样,你也应该知道是如何编码的,并使用base64.StdEncodingbase64.RawStdEncoding,不是两者都有。您不需要猜测这些事情,而只需使用与发送方使用的编码相对应的decode方法。

Base64编码可以不同:

  • 填充/未填充(末尾没有=s)
  • 标准(+,/)或URL (-,_)字母
  • 带/不带换行符(例如MIME以76个字符分隔行,PEM以64个字符分隔行)

您可以直观地检查编码字符串以猜测编码方案。但请注意,填充并不总是存在-它取决于源数据的长度是否为3的倍数,因为每个3字节的元组被编码为4个6位字符。

最新更新