简体   繁体   English

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

[英]Use base64.StdEncoding or base64.RawStdEncoding to decode base64 string in Go

As we know, there are two methods to decode base64 string in go base64.StdEncoding or base64.RawStdEncoding .我们知道,在 go base64.StdEncodingbase64.RawStdEncoding有两种方法可以解码 base64 字符串。 How to use one of them correctly to decode one base64 string?如何正确使用其中之一来解码一个 base64 字符串? If the incorrect encoding method is invoked.如果调用了不正确的编码方法。 For example, if RawStdEncoding is used to decode one StdEncoding string, the error illegal base64 data at input byte xxx will come up.例如,如果使用RawStdEncoding对一个StdEncoding字符串进行解码,则会出现illegal base64 data at input byte xxx错误。

Per doc每个文档

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

RawStdEncoding is the standard raw, unpadded base64 encoding, as defined in RFC 4648 section 3.2. RawStdEncoding 是标准的原始、未填充的 base64 编码,如 RFC 4648 第 3.2 节中所定义。 This is the same as StdEncoding but omits padding characters.这与 StdEncoding 相同,但省略了填充字符。

Should we distinguish them by checking the end of padding is StdPadding or not?我们是否应该通过检查填充的结尾是否为StdPadding来区分它们? code snippet代码片段

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

Is that an elegant way to do that?这是一种优雅的方式吗? Or anything am I missing?或者我错过了什么? What is the elegant way to decode base64 string?解码base64字符串的优雅方法是什么?

Update:更新:

Maybe one raw way to do it through error checking as below也许是通过错误检查来做到这一点的一种原始方法,如下所示

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

As we know, there are two methods to decode base64 string in go base64.StdEncoding or base64.RawStdEncoding.我们知道,在 go base64.StdEncoding 或 base64.RawStdEncoding 中有两种方法可以解码 base64 字符串。

there's also base64.URLEncoding which uses characters - and _ as substitutes for the URL-unsafe base64 characters + and / .还有base64.URLEncoding使用字符-_作为 URL 不安全的 base64 字符+/替代品。

Should we distinguish them by checking the end of padding is StdPadding or not?我们是否应该通过检查填充的结尾是否为 StdPadding 来区分它们? code snippet代码片段

This won't work.这行不通。 There is a 1 in 3 chance that a base64 encoding will have no visible padding: 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 https://play.golang.org/p/LMtIHlyXdn7

so how do you tell them apart - and determine which encoding was used?那么你如何区分它们 - 并确定使用了哪种编码?


Yes you can-double decode like in your updated Question:是的,您可以像在更新的问题中一样进行双重解码:

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

There are some tricks you can employ to make some educated guesses.您可以使用一些技巧来做出一些有根据的猜测。 For example:例如:

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

If you get illegal base64 data at input byte ... then:如果您illegal base64 data at input byte ...得到illegal base64 data at input byte ...那么:

  • you either used the wrong base64 decoder, or您要么使用了错误的 base64 解码器,要么
  • there's more data after the base64 string that must be stripped before invoking the decoder, or在调用解码器之前必须去除 base64 字符串之后的更多数据,或者
  • the input is not base64.输入不是 base64。

Should we distinguish them by checking the end of padding is StdPadding or not?我们是否应该通过检查填充的结尾是否为 StdPadding 来区分它们?

No. Just like you know that the data is at all base64-encoded, you should also know how exactly it is encoded and use eg either base64.StdEncoding or base64.RawStdEncoding , not both.号就像你知道的数据是,在所有的base64编码,你也应该知道如究竟是如何被编码和兼用base64.StdEncodingbase64.RawStdEncoding ,不能同时使用。 You don't guess these things, but simply use the decode method that corresponds to the encoding used by the sender.这些东西你不用猜,直接用对应发送方使用的编码的decode方法就可以了。

Base64 encoding can differ by: Base64 编码的不同之处在于:

  • padded/unpadded (no = s at the end)填充/未填充(最后没有= s)
  • standard ( + , / ) or URL ( - , _ ) alphabet标准 ( + , / ) 或 URL ( - , _ ) 字母
  • with/without newlines (eg MIME splits lines on 76 characters, PEM on 64)带/不带换行符(例如 MIME 在 76 个字符上拆分行,在 64 个字符上拆分 PEM)

You can visually inspect the encoded string to guess the encoding scheme.您可以直观地检查编码字符串以猜测编码方案。 But note that padding is not always present - it depends on whether the length of source data is a multiple of 3 or not, since each tuple of 3 bytes is encoded as 4 6-bit characters.但请注意,填充并不总是存在 - 这取决于源数据的长度是否为 3 的倍数,因为每个 3 字节的元组都被编码为 4 个 6 位字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM