Go encoding/base64 解码指南

·Systems Engineer·审阅者Hana Nováková·发布日期

直接在浏览器中使用免费的 Base64解码器,无需安装。

在线试用 Base64解码器 →

Base64 解码在 Go 开发中随处可见——JWT 检查、二进制文件附件、云服务 API 载荷。Go 的标准库 encoding/base64能处理所有这些场景,但选错编码变体(标准 vs URL 安全、有填充 vs 无填充)是导致 “illegal base64 data” 错误的最常见原因。本指南涵盖 StdEncodingURLEncodingRawURLEncoding、使用 base64.NewDecoder 进行流式解码、JWT 载荷检查,以及几乎所有人第一次都会踩的四个常见错误。如需在浏览器中快速解码, ToolDeck 的 Base64 Decoder 无需编写任何代码即可即时完成。

  • encoding/base64 是 Go 标准库的一部分,无需 go get
  • 对于 JWT 令牌和大多数现代 API,使用 RawURLEncoding(无填充,URL 安全字母表)
  • StdEncoding 使用 + 和 / 及 = 填充;URLEncoding 替换为 - 和 _,但保留填充
  • base64.NewDecoder 可包装任意 io.Reader,实现流式解码而无需全部载入内存
  • 务必检查返回的错误——无效填充和错误字母表都会产生 illegal base64 data 错误

什么是 Base64 解码?

Base64 编码使用 64 个可打印字符(A–Z、a–z、0–9 以及两个额外字符)将二进制数据表示为 ASCII 文本。解码则是逆向操作——将该 ASCII 表示还原为原始字节。每 4 个 Base64 字符精确解码为 3 个字节。 该方案的存在是因为许多传输层(电子邮件、HTTP 头部、JSON 字段)是为文本而非原始二进制设计的。 以下是完整的编解码往返示例:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// Raw bytes → Base64 encoded → decoded back to raw bytes
	original := []byte("service_token:xK9mP2qR")
	// Encoded: "c2VydmljZV90b2tlbjp4SzltUDJxUg=="

	encoded := base64.StdEncoding.EncodeToString(original)
	decoded, _ := base64.StdEncoding.DecodeString(encoded)
	fmt.Println(string(decoded) == string(original)) // true
}

使用 encoding/base64 在 Go 中解码 Base64

encoding/base64 包随 Go 一同提供,无需任何外部依赖。它以包级变量的形式暴露了四种预定义的编码变体。处理字符串输入最常用的函数是 DecodeString,返回一个字节切片和一个错误值。

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	// Standard Base64 — the alphabet uses + and / with = padding
	encoded := "eyJob3N0IjoiZGItcHJvZCF1cy1lYXN0LTEiLCJwb3J0Ijo1NDMyfQ=="
	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode error: %v", err)
	}
	fmt.Println(string(decoded))
	// {"host":"db-prod.us-east-1","port":5432}
}

Decode 方法处理字节切片而非字符串,并将结果写入预分配的目标缓冲区。你需要正确设置缓冲区大小——使用 base64.StdEncoding.DecodedLen(len(src)) 获取最大大小(由于填充原因,该值可能比实际解码长度多几个字节)。

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	src := []byte("eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9")
	dst := make([]byte, base64.RawStdEncoding.DecodedLen(len(src)))

	n, err := base64.RawStdEncoding.Decode(dst, src)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(dst[:n]))
	// {"host":"db-prod","port":5432}
}
注意:DecodedLen 返回的是上界,而非精确长度。务必使用 Decode 的返回值 n 来正确截取结果: dst[:n]

StdEncoding vs URLEncoding——选择正确的变体

这是最容易产生混淆的地方。Go 的 encoding/base64 暴露了四种编码对象,选错一种必然报错。区别在于两点:字母表和填充。

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// JWT header payload — URL-safe, no padding
	jwtHeader := "eyJhbGciOiJSUzI1NiIsImtpZCI6IjIwMjMtMDkifQ"

	// Wrong: StdEncoding fails on URL-safe input without padding
	_, err1 := base64.StdEncoding.DecodeString(jwtHeader)
	fmt.Println("StdEncoding error:", err1)
	// StdEncoding error: illegal base64 data at input byte 43

	// Correct: RawURLEncoding — no padding, URL-safe alphabet
	decoded, err2 := base64.RawURLEncoding.DecodeString(jwtHeader)
	fmt.Println("RawURLEncoding ok:", err2, "→", string(decoded))
	// RawURLEncoding ok: <nil> → {"alg":"RS256","kid":"2023-09"}
}

四种变体的简明说明:

函数 / 方法
编码方式
是否需要填充
返回值
base64.StdEncoding.DecodeString(s)
标准 (+, /)
是 (=)
([]byte, error)
base64.URLEncoding.DecodeString(s)
URL 安全 (-, _)
是 (=)
([]byte, error)
base64.RawStdEncoding.DecodeString(s)
标准 (+, /)
([]byte, error)
base64.RawURLEncoding.DecodeString(s)
URL 安全 (-, _)
([]byte, error)
base64.StdEncoding.Decode(dst, src)
标准 (+, /)
是 (=)
(n int, error)
base64.NewDecoder(enc, r)
任意编码
io.Reader

我的经验法则:如果数据来自 JWT、OAuth 流程或云服务商 SDK,优先用 RawURLEncoding。如果来自电子邮件附件或传统 Web 表单,先试 StdEncoding。错误信息会告诉你解码失败的确切字节位置。

从文件和 API 响应中解码 Base64

读取 Base64 编码的文件

二进制文件(图片、PDF、证书)有时以 Base64 编码形式存储在磁盘上。读取文件,去除末尾空白字符,然后解码:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"os"
	"strings"
)

func main() {
	raw, err := os.ReadFile("certificate.pem.b64")
	if err != nil {
		log.Fatalf("read file: %v", err)
	}

	// Strip newlines — Base64 files often have line breaks every 76 chars
	cleaned := strings.ReplaceAll(strings.TrimSpace(string(raw)), "\n", "")

	decoded, err := base64.StdEncoding.DecodeString(cleaned)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}

	if err := os.WriteFile("certificate.pem", decoded, 0600); err != nil {
		log.Fatalf("write: %v", err)
	}
	fmt.Printf("decoded %d bytes → certificate.pem\n", len(decoded))
}

解码 API JSON 响应中的 Base64 字段

云 API 经常将二进制数据(加密密钥、签名数据块、缩略图)作为 JSON 中的 Base64 字符串返回。先反序列化 JSON,再解码目标字段:

Go 1.21+
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

type SecretResponse struct {
	Name    string `json:"name"`
	Payload string `json:"payload"` // Base64-encoded secret value
	Version int    `json:"version"`
}

func fetchAndDecodeSecret(secretURL string) ([]byte, error) {
	resp, err := http.Get(secretURL)
	if err != nil {
		return nil, fmt.Errorf("http get: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("unexpected status: %d", resp.StatusCode)
	}

	var secret SecretResponse
	if err := json.NewDecoder(resp.Body).Decode(&secret); err != nil {
		return nil, fmt.Errorf("decode json: %w", err)
	}

	value, err := base64.StdEncoding.DecodeString(secret.Payload)
	if err != nil {
		return nil, fmt.Errorf("decode base64: %w", err)
	}
	return value, nil
}

func main() {
	value, err := fetchAndDecodeSecret("https://api.example.com/secrets/db-password")
	if err != nil {
		log.Fatalf("fetch secret: %v", err)
	}
	fmt.Printf("secret value: %s\n", value)
}
注意:使用 fmt.Errorf("decode base64: %w", err) 包装错误而非丢失上下文。encoding/base64 原始错误信息包含失败的字节位置,在调试时非常有用。

流式处理大型 Base64 编码文件

os.ReadFile 将 500 MB 的 Base64 编码文件载入内存再调用 DecodeString,大约需要 750 MB 内存(编码字符串加上解码后的字节)。base64.NewDecoder 可以包装任意 io.Reader 并按块解码,使内存占用保持近似恒定。结合 io.Copy 可构建简洁的流式处理管道:

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"io"
	"log"
	"os"
)

func streamDecodeFile(srcPath, dstPath string) error {
	src, err := os.Open(srcPath)
	if err != nil {
		return fmt.Errorf("open source: %w", err)
	}
	defer src.Close()

	dst, err := os.Create(dstPath)
	if err != nil {
		return fmt.Errorf("create dest: %w", err)
	}
	defer dst.Close()

	decoder := base64.NewDecoder(base64.StdEncoding, src)
	written, err := io.Copy(dst, decoder)
	if err != nil {
		return fmt.Errorf("stream decode: %w", err)
	}
	fmt.Printf("written %d bytes to %s\n", written, dstPath)
	return nil
}

func main() {
	if err := streamDecodeFile("backup.tar.b64", "backup.tar"); err != nil {
		log.Fatal(err)
	}
}
警告:base64.NewDecoder 期望接收干净、连续的 Base64 数据。如果源文件含有换行符(PEM 和 MIME 编码文件中很常见),请在流式传输前用行剥离读取器包装源 reader,或预处理文件以移除换行符。

从命令行解码 Base64

大多数 Go 开发者在调试时首先会使用命令行。macOS 和 Linux 系统均内置 base64 命令;在 Windows 上,PowerShell 有等效的内置命令。对于快速检查 API 载荷,这些方式比编写 Go 脚本更高效。

bash
# Decode a Base64 string (Linux / macOS)
echo "eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9" | base64 --decode
# {"host":"db-prod","port":5432}

# Decode and pretty-print with jq (pipe the JSON output)
echo "eyJob3N0IjoiZGItcHJvZCIsInBvcnQiOjU0MzJ9" | base64 --decode | jq .
# {
#   "host": "db-prod",
#   "port": 5432
# }

# Decode a Base64-encoded file to binary
base64 --decode < encrypted_payload.b64 > encrypted_payload.bin

# macOS uses -D flag instead of --decode
echo "c2VjcmV0LXRva2Vu" | base64 -D

如需在不安装任何工具的情况下检查 JWT 令牌,将令牌粘贴到 ToolDeck 的 Base64 Decoder 中——以点号分割后逐段解码即可。

高性能替代方案:encoding/base64 本身已经足够快

与 Python 中 orjsonjson 之间存在明显性能差距不同,Go 的 encoding/base64 已经过汇编优化,对大多数工作负载而言足够快。但如果你需要在紧循环中处理数百万条记录,filippo.io/base64 提供了 SIMD 加速解码,且 API 与标准库完全兼容。

bash
go get filippo.io/base64
Go 1.21+
package main

import (
	"fmt"
	"log"

	"filippo.io/base64"
)

func main() {
	// Drop-in replacement — same API as encoding/base64
	encoded := "eyJob3N0IjoiY2FjaGUtcHJvZCIsInBvcnQiOjYzNzl9"
	decoded, err := base64.StdEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(decoded))
	// {"host":"cache-prod","port":6379}
}

性能提升在支持 AVX2 的 amd64 架构上最为明显——基准测试显示大输入的吞吐量提升 2–4 倍。对于日常 API 响应解码(每次仅几百字节),使用标准库即可。

在 Go 中解码 Base64 JWT 载荷

几乎每个后端服务都会遇到 JWT 检查需求。根据我的经验,大多数调试会归结为"这个令牌里到底有什么?"——你完全可以不引入完整的 JWT 库来回答这个问题。令牌由三个以点号分隔的 Base64url 编码片段组成,中间那个片段才是你真正关心的载荷:

Go 1.21+
package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"log"
	"strings"
)

type JWTPayload struct {
	Subject  string   `json:"sub"`
	Issuer   string   `json:"iss"`
	Expiry   int64    `json:"exp"`
	Roles    []string `json:"roles"`
}

func decodeJWTPayload(token string) (*JWTPayload, error) {
	parts := strings.Split(token, ".")
	if len(parts) != 3 {
		return nil, fmt.Errorf("invalid JWT: expected 3 segments, got %d", len(parts))
	}

	// JWT uses RawURLEncoding — URL-safe alphabet, no = padding
	raw, err := base64.RawURLEncoding.DecodeString(parts[1])
	if err != nil {
		return nil, fmt.Errorf("decode payload: %w", err)
	}

	var payload JWTPayload
	if err := json.Unmarshal(raw, &payload); err != nil {
		return nil, fmt.Errorf("unmarshal payload: %w", err)
	}
	return &payload, nil
}

func main() {
	token := "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3ItNDQyIiwiaXNzIjoiYXV0aC5leGFtcGxlLmNvbSIsImV4cCI6MTc0MTk1NjgwMCwicm9sZXMiOlsiYWRtaW4iLCJhdWRpdG9yIl19.SIGNATURE"

	payload, err := decodeJWTPayload(token)
	if err != nil {
		log.Fatalf("jwt: %v", err)
	}
	fmt.Printf("Subject: %s\n", payload.Subject)
	fmt.Printf("Issuer:  %s\n", payload.Issuer)
	fmt.Printf("Roles:   %v\n", payload.Roles)
	// Subject: usr-442
	// Issuer:  auth.example.com
	// Roles:   [admin auditor]
}

常见错误

以下四种错误我在真实代码审查中都遇到过——前两种在集成新认证提供商时几乎每次都会出现。

对 URL 安全输入使用 StdEncoding

问题: JWT 令牌和 OAuth 令牌使用 URL 安全的 Base64 字母表(- 和 _)。将它们传给 StdEncoding.DecodeString 会报 'illegal base64 data' 错误。

解决方案: 检查数据来源:认证系统的令牌使用 RawURLEncoding;二进制附件使用 StdEncoding。

Before · Go
After · Go
// JWT header — URL-safe, no padding
token := "eyJhbGciOiJSUzI1NiJ9"
decoded, err := base64.StdEncoding.DecodeString(token)
// err: illegal base64 data at input byte 19
// JWT header — correct encoding
token := "eyJhbGciOiJSUzI1NiJ9"
decoded, err := base64.RawURLEncoding.DecodeString(token)
// decoded: {"alg":"RS256"}
// err: nil
忽略 Decode 的 n 返回值

问题: Decode 写入预分配缓冲区并返回实际写入的字节数。DecodedLen 返回的是上界,因此缓冲区末尾可能包含垃圾字节。

解决方案: 始终使用 dst[:n] 而非 dst[:len(dst)] 截取结果。

Before · Go
After · Go
dst := make([]byte, base64.StdEncoding.DecodedLen(len(src)))
base64.StdEncoding.Decode(dst, src)
fmt.Println(string(dst)) // may include trailing zero bytes
dst := make([]byte, base64.StdEncoding.DecodedLen(len(src)))
n, err := base64.StdEncoding.Decode(dst, src)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(dst[:n])) // correct — only the decoded bytes
解码前未去除空白字符

问题: 从终端、电子邮件或配置文件复制的 Base64 字符串通常带有末尾换行符或空格。直接传给 DecodeString 会在空白字符处报错。

解决方案: 解码前调用 strings.TrimSpace(对于嵌入的换行符还需调用 strings.ReplaceAll)。

Before · Go
After · Go
// Value read from a config file with a trailing newline
encoded := "c2VydmljZV9rZXk6eEtNcDI=\n"
decoded, err := base64.StdEncoding.DecodeString(encoded)
// err: illegal base64 data at input byte 24
encoded := "c2VydmljZV9rZXk6eEtNcDI=\n"
cleaned := strings.TrimSpace(encoded)
decoded, err := base64.StdEncoding.DecodeString(cleaned)
// decoded: "service_key:xKMp2"
// err: nil
将解码后的字节错误地转换为字符串

问题: 对二进制数据(图片、压缩载荷)调用 string(decoded) 会产生无效的 UTF-8 字符串。Go 字符串可以持有任意字节,但某些操作会破坏内容。

解决方案: 在整个处理管道中保持二进制数据为 []byte 类型。只有在确认解码内容为文本时,才调用 string(decoded)。

Before · Go
After · Go
decoded, _ := base64.StdEncoding.DecodeString(pngBase64)
// Treating binary PNG as a string loses data
imageStr := string(decoded)
os.WriteFile("image.png", []byte(imageStr), 0644) // may corrupt
decoded, err := base64.StdEncoding.DecodeString(pngBase64)
if err != nil {
    log.Fatal(err)
}
// Write bytes directly — no string conversion
os.WriteFile("image.png", decoded, 0644)

方法对比

所有变体均随标准库提供,无需任何外部依赖。

方法
输入类型
编码变体
流式处理
自定义字母表
自定义填充
是否需要安装
StdEncoding.DecodeString
string
标准
否(标准库)
URLEncoding.DecodeString
string
URL 安全
否(标准库)
RawStdEncoding.DecodeString
string
标准(无填充)
否(标准库)
RawURLEncoding.DecodeString
string
URL 安全(无填充)
否(标准库)
StdEncoding.Decode
[]byte
标准
否(标准库)
base64.NewDecoder
io.Reader
任意
否(标准库)
encoding/base64 + NewEncoding
string
自定义字母表
否(标准库)

JWT 令牌和 OAuth 流程使用 RawURLEncoding。电子邮件附件和 MIME 数据使用 StdEncoding。处理来自磁盘或网络的大型二进制文件时,将 reader 包装在 base64.NewDecoder 中——无论文件大小,内存占用都保持恒定。需要自定义字母表?base64.NewEncoding(alphabet) 可为特殊场景构建新的编码对象。

在开发过程中进行快速一次性检查时, 在线 Base64 Decoder 比启动一个 Go 程序更快捷。

常见问题

如何在 Go 中解码 Base64 字符串?

导入 encoding/base64 并调用 base64.StdEncoding.DecodeString(s)。该函数返回 ([]byte, error)——务必检查错误。如果字符串使用 URL 安全字符(- 和 _ 替代 + 和 /),请改用 base64.URLEncoding.DecodeString。对于 JWT 令牌和大多数现代 API,RawURLEncoding(无填充)是正确选择。

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
)

func main() {
	encoded := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
	decoded, err := base64.RawURLEncoding.DecodeString(encoded)
	if err != nil {
		log.Fatalf("decode: %v", err)
	}
	fmt.Println(string(decoded))
	// {"alg":"HS256","typ":"JWT"}
}

Go 中 StdEncoding 与 URLEncoding 有什么区别?

StdEncoding 使用标准 Base64 字母表,包含 + 和 / 字符及 = 填充,定义于 RFC 4648 第 4 节。URLEncoding 将 + 替换为 -,将 / 替换为 _,使输出可安全用于 URL 和 HTTP 头部而无需百分比编码,定义于 RFC 4648 第 5 节。JWT 令牌、OAuth 令牌以及嵌入查询字符串的数据应使用 URLEncoding。

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	// Standard: may contain + / and = characters
	std := base64.StdEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(std) // "aGVsbG8vd29ybGQ="

	// URL-safe: replaces + with - and / with _
	url := base64.URLEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(url) // "aGVsbG8vd29ybGQ=" (same — diff shows with different bytes)

	// JWT headers never have padding — use RawURLEncoding
	raw := base64.RawURLEncoding.EncodeToString([]byte("hello/world"))
	fmt.Println(raw) // "aGVsbG8vd29ybGQ" (no trailing =)
}

如何修复 Go 中的 "illegal base64 data" 错误?

该错误表示输入包含超出预期字母表的字符,或填充不正确。三种常见原因:对 URL 安全输入使用了 StdEncoding(换用 URLEncoding);对无填充输入使用了有填充的编码器(换用 RawStdEncoding/RawURLEncoding);输入末尾含有空白字符或换行符。解码前使用 strings.TrimSpace 去除空白字符。

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"strings"
)

func main() {
	// Input from a webhook payload — has newlines stripped from wire format
	raw := "  aGVsbG8gd29ybGQ=  \n"
	cleaned := strings.TrimSpace(raw)

	decoded, err := base64.StdEncoding.DecodeString(cleaned)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(decoded)) // hello world
}

如何在 Go 中流式解码大型 Base64 编码文件?

使用 base64.NewDecoder(base64.StdEncoding, reader),它可以包装任意 io.Reader 并按需解码。通过 io.Copy 将其导流到目标位置,无需将整个文件缓冲到内存中。这是解码 Base64 编码二进制附件或大型数据载荷的标准模式。

Go 1.21+
package main

import (
	"encoding/base64"
	"io"
	"log"
	"os"
)

func main() {
	src, err := os.Open("attachment.b64")
	if err != nil {
		log.Fatal(err)
	}
	defer src.Close()

	dst, err := os.Create("attachment.bin")
	if err != nil {
		log.Fatal(err)
	}
	defer dst.Close()

	decoder := base64.NewDecoder(base64.StdEncoding, src)
	io.Copy(dst, decoder)
}

在 Go 中不使用 JWT 库能解码 Base64 JWT 载荷吗?

可以。JWT 是三个以点号分隔的 Base64url 编码片段。以 "." 分割后,用 base64.RawURLEncoding.DecodeString 解码第二个片段(索引 1)即可——JWT 头部和载荷使用 URL 安全字母表且不含填充。第三个片段(索引 2)是二进制签名,通常只在验证时需要。

Go 1.21+
package main

import (
	"encoding/base64"
	"fmt"
	"log"
	"strings"
)

func main() {
	token := "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3ItOTAxIiwicm9sZSI6ImFkbWluIn0.SIG"
	parts := strings.Split(token, ".")
	if len(parts) < 2 {
		log.Fatal("invalid JWT format")
	}

	payload, err := base64.RawURLEncoding.DecodeString(parts[1])
	if err != nil {
		log.Fatalf("decode payload: %v", err)
	}
	fmt.Println(string(payload))
	// {"sub":"usr-901","role":"admin"}
}

解码 HTTP API 响应中的 Base64 数据应使用哪种编码?

查阅 API 文档或检查编码后的字符串。如果包含 + 或 / 字符且以 = 结尾,使用 StdEncoding。如果使用 - 和 _ 字符且无 =,使用 RawURLEncoding。不确定时先试 RawURLEncoding——大多数现代 API(OAuth2、JWT、Google Cloud、AWS)使用无填充的 URL 安全 Base64。

Go 1.21+
package main

import (
	"encoding/base64"
	"strings"
)

// Detect encoding variant from the encoded string
func decodeAPIPayload(encoded string) ([]byte, error) {
	// URL-safe characters without padding — common in modern APIs
	if !strings.Contains(encoded, "+") && !strings.Contains(encoded, "/") {
		return base64.RawURLEncoding.DecodeString(encoded)
	}
	// Standard Base64 with padding
	return base64.StdEncoding.DecodeString(encoded)
}

相关工具

  • Base64 Encoder — 在浏览器中将二进制数据或文本编码为 Base64,便于生成测试用例并粘贴到 Go 单元测试中。
  • JWT Decoder — 一次性分割并解码所有三个 JWT 片段,并逐字段检查载荷——调试时无需编写任何 Go 代码。
  • URL Decoder — 对 URL 编码字符串进行百分比解码,在 API 响应混合了 Base64url 数据和百分比编码查询参数时非常实用。
  • JSON Formatter — 解码 Base64 JWT 载荷或 API 响应后,将 JSON 粘贴到此处即可即时美化输出并验证结构。
JO
James OkaforSystems Engineer

James is a systems engineer and Go enthusiast who focuses on high-performance microservices, command-line tooling, and infrastructure automation. He enjoys the simplicity and explicitness of Go and writes about building fast, reliable backend systems. When not coding he explores distributed systems concepts and contributes to open-source Go libraries.

HN
Hana Nováková技术审阅者

Hana is a backend engineer who has built production gRPC and REST services in Go for cloud-native environments. She cares deeply about API correctness, protobuf schema design, and the operational side of running Go services in Kubernetes. She writes about the Go standard library, encoding and marshalling patterns, gRPC best practices, and the subtleties of writing idiomatic Go that is easy to test and maintain.