go - 在 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)
}
解决方案
众所周知,在 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?
}
推荐阅读
- flutter - 具有相同 key.jks 的颤振签名应用程序不起作用
- javascript - 订阅函数中未定义的组件变量
- javascript - 元素的值被 JavaScript 改变了两次
- azure - 如何知道 Azure PowerShell 中附加到 VM 的子网名称?
- java - 如何在单击按钮时更改列表项的背景颜色?
- java - Angular Post 请求进入挂起状态并且没有命中服务器
- linux - 列出文件夹中的基本文件,其中包含多个带有日期戳的文件版本
- java - 通过登录页面以使用 JSoup 进行网络爬虫
- recursion - 创建交错元素列表:Prolog
- sql - 将列移动到行