如何使用Golang encoding/base64进行编码与解码_Golang base64操作示例

base64.StdEncoding.EncodeToString是最常用编码方法,将[]byte转为标准Base64字符串,需注意nil切片panic、无换行及填充要求;DecodeString必须检查error,非法字符、长度非4倍数或填充错误均导致失败;URL场景应使用URLEncoding避免+和/;大容量处理宜用Encode/Decode直接操作字节切片以避免内存拷贝。

base64.StdEncoding.EncodeToString 是最常用的编码入口

直接把 []byte 转成 base64 字符串,无需手动管理缓冲区。它内部使用标准 base64 字母表(A-Z a-z 0-9 + /),末尾用 = 补齐。

常见错误是传入 nil 或未初始化的切片,会 panic;另外注意它不处理换行或空格——如果协议要求每 76 字节换行(如 MIME),得用 base64.StdEncoding.WithPadding(base64.NoPadding) 配合手动分段,或改用 base64.Encoder 写入 io.Writer

示例:

package main

import (
    "encoding/base64"
    "fmt"
)

func main() {
    data := []byte("hello world")
    encoded := base64.StdEncoding.EncodeToString(data)
    fmt.Println(encoded) // aGVsbG8gd29ybGQ=
}

base64.StdEncoding.DecodeString 必须处理 error

解码失败不会静默忽略,而是返回非 nil 的 error,典型原因包括:字符串含非法字符(如中文、空格)、长度不是 4 的倍数、填充符位置错(如中间出现 =)。

不要忽略返回的 err,尤其在解析外部输入(HTTP header、URL 参数)时。若需容忍不规范输入(比如去掉空格再试),应先清洗字符串。

要点:

  • DecodeString 要求输入严格符合 base64 编码规则
  • 若原始数据可能被 URL 编码过(如 + 替换为空格),需先调用 strings.ReplaceAll(s, " ", "+")
  • 对 URL 安全 base64(用 -_ 替代 +/),必须用 base64.URLEncoding,混用会解码失败

示例:

decoded, err := base64.StdEncoding.DecodeString("aGVsbG8gd29ybGQ=")
if err != nil {
    panic(err) // e.g. illegal base64 data at input byte 0
}
fmt.Printf("%s\n", decoded) // hello world

base64.URLEncoding 用于 JWT、URL 参数等场景

标准 base64 的 +/ 在 URL 或文件名中不安全,base64.URLEncoding 改用 -_,且默认无填充(= 被省略)。这意味着:

你不能直接把 URLEncoding.EncodeToString 的结果喂给 StdEncoding.DecodeString,反之亦然——会报 illegal base64 data

JWT 头部和载荷通常用 URL-safe base64,但签名部分有时保留填充;解析时建议统一用 URLEncoding 并手动补足长度(4 的倍数),再解码。

示例(带填充兼容):

s := "aGVsbG8" // missing padding
for len(s)%4 != 0 {
    s += "="
}
data, _ := base64.URLEncoding.DecodeString(s)

避免内存重复拷贝:用 Encode/Decode 直接操作字节切片

当处理大文件或高频调用时,EncodeToStringDecodeString 会额外分配字符串内存。若已有目标缓冲区,可用:

  • base64.StdEncoding.Encode(dst, src):把 src 编码进预先分配的 dst(长度 ≥ base64.StdEncoding.EncodedLen(len(src))
  • base64.StdEncoding.Decode(dst, src):解码到 dst(长度 ≥ base64.StdEncoding.DecodedLen(len(src))

这两个函数返回实际写入字节数,且不涉及字符串转换,适合性能敏感路径。注意:它们不检查 dst 容量是否足够,越界会 panic。

容易被忽略的一点:不同 encoding 实例(如 StdEncoding vs URLEncoding)的 EncodedLen 结果相同,但 DecodedLen 可能因填充策略不同而异——务必用对应实例的方法计算目标切片长度。