Files
encryptx/base64x/base64x.go
T

150 lines
5.8 KiB
Go
Raw Normal View History

2026-09-30 15:49:12 +08:00
// Package base64x 提供 Base64 编解码的统一 []byte API。
//
// 本包是 encoding/base64 的薄封装,统一了输入输出类型(一律使用 []byte)
// 与错误行为(解码失败一律返回 nil 切片与包装后的 error,绝不返回部分结果),
// 并提供友好、可读的错误信息。
//
// 四个变体的适用场景:
//
// - Encode / Decode:RFC 4648 标准字母表(+/)且带 = 填充。
// 适合 MIME、邮件、PEM 等传统场景;字符 + 与 / 不能直接放进 URL 查询串
// 或文件名(会被转义或截断)。
// - EncodeURL / DecodeURL:URL 与文件名安全字母表(-_)且带 = 填充。
// 适合 Cookie、HTTP 头、文件名,但 = 在某些上下文(如 JWT、部分 URL 解析器)
// 仍需转义。
// - EncodeRaw / DecodeRaw:标准字母表、**无填充**。
// 适合放进 JSON、YAML、定长字段(长度必须是 4 的倍数约束被去掉)。
// - EncodeRawURL / DecodeRawURL:URL 安全字母表、**无填充**。
// 适合 URL 路径/查询串、文件名与 JSON(最通用的可打印编码);
// 本包推荐在不确定场景时优先使用它。
//
// 安全注意:Base64 是**编码**而非加密,不提供任何机密性,
// 任何人都能还原原文;敏感数据必须先加密再编码。
// 解码不可信输入时应注意结果长度可能约为输入的 3/4,
// 需要限制输入大小以防内存放大类拒绝服务。
2023-12-27 19:00:14 +08:00
package base64x
2026-09-30 15:49:12 +08:00
import (
"encoding/base64"
"fmt"
)
2023-12-27 19:00:14 +08:00
2026-09-30 15:49:12 +08:00
// Encode 使用标准 Base64 字母表(+/)编码数据,输出带 = 填充。
//
// 参数:
// - data: 待编码的字节串,可以为 nil(返回空字符串)。
//
// 返回值:标准 Base64 字符串,长度总是 4 的倍数。
//
// 安全注意:Base64 不提供机密性;且标准字母表含 + 与 /,
// 不要直接用于 URL 或文件名,请使用 EncodeURL 或 EncodeRawURL。
func Encode(data []byte) string {
return base64.StdEncoding.EncodeToString(data)
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
// Decode 解码标准 Base64 字符串(要求带正确的 = 填充)。
//
// 参数:
// - s: 待解码的标准 Base64 字符串。
//
// 返回值:解码后的字节串;失败时返回 nil 与包装后的 error。
//
// 安全注意:失败时不会返回任何部分解码结果,避免调用方误用不完整数据;
// 解码结果可能很长,处理不可信输入前应限制输入长度。
func Decode(s string) ([]byte, error) {
decoded, err := base64.StdEncoding.DecodeString(s)
2023-12-27 19:00:14 +08:00
if err != nil {
2026-09-30 15:49:12 +08:00
return nil, fmt.Errorf("标准 Base64 解码失败: %w", err)
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
return decoded, nil
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
// EncodeURL 使用 URL/文件名安全字母表(-_)编码数据,输出带 = 填充。
//
// 参数:
// - data: 待编码的字节串,可以为 nil(返回空字符串)。
//
// 返回值:URL 安全 Base64 字符串,长度总是 4 的倍数。
//
// 安全注意:字母表不含 + 与 /,可安全用于 URL 与文件名;
// 但 = 填充在某些上下文仍需转义,若需彻底避免请使用 EncodeRawURL。
func EncodeURL(data []byte) string {
return base64.URLEncoding.EncodeToString(data)
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
// DecodeURL 解码 URL 安全 Base64 字符串(要求带正确的 = 填充)。
//
// 参数:
// - s: 待解码的 URL 安全 Base64 字符串。
//
// 返回值:解码后的字节串;失败时返回 nil 与包装后的 error。
//
// 安全注意:失败时不会返回部分结果;本函数不接受标准字母表中的 + 与 /。
func DecodeURL(s string) ([]byte, error) {
decoded, err := base64.URLEncoding.DecodeString(s)
2023-12-27 19:00:14 +08:00
if err != nil {
2026-09-30 15:49:12 +08:00
return nil, fmt.Errorf("URL 安全 Base64 解码失败: %w", err)
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
return decoded, nil
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
// EncodeRaw 使用标准 Base64 字母表(+/)编码数据,输出**不带** = 填充。
//
// 参数:
// - data: 待编码的字节串,可以为 nil(返回空字符串)。
//
// 返回值:无填充的标准 Base64 字符串,长度不再保证是 4 的倍数。
//
// 安全注意:无填充版本更适合放进 JSON、定长字段;但字母表仍含 + 与 /,
// 不要直接用于 URL 或文件名。
func EncodeRaw(data []byte) string {
return base64.RawStdEncoding.EncodeToString(data)
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
// DecodeRaw 解码无填充的标准 Base64 字符串。
//
// 参数:
// - s: 待解码的无填充标准 Base64 字符串。
//
// 返回值:解码后的字节串;失败时返回 nil 与包装后的 error。
//
// 安全注意:失败时不会返回部分结果;带 = 填充的输入会被拒绝。
func DecodeRaw(s string) ([]byte, error) {
decoded, err := base64.RawStdEncoding.DecodeString(s)
2023-12-27 19:00:14 +08:00
if err != nil {
2026-09-30 15:49:12 +08:00
return nil, fmt.Errorf("无填充标准 Base64 解码失败: %w", err)
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
return decoded, nil
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
// EncodeRawURL 使用 URL/文件名安全字母表(-_)编码数据,输出**不带** = 填充。
//
// 参数:
// - data: 待编码的字节串,可以为 nil(返回空字符串)。
//
// 返回值:URL 安全且无填充的 Base64 字符串,可直接放进 URL 路径、
// 查询串、文件名与 JSON 字符串。
//
// 安全注意:这是本包适用面最广的编码,但仍然只是编码:
// 若数据是秘密,必须先加密(例如 AES-GCM)后再编码。
func EncodeRawURL(data []byte) string {
return base64.RawURLEncoding.EncodeToString(data)
2023-12-27 19:00:14 +08:00
}
2026-09-30 15:49:12 +08:00
// DecodeRawURL 解码 URL 安全且无填充的 Base64 字符串。
//
// 参数:
// - s: 待解码的 URL 安全无填充 Base64 字符串。
//
// 返回值:解码后的字节串;失败时返回 nil 与包装后的 error。
//
// 安全注意:失败时不会返回部分结果;输入中的 = 填充、
// +、/ 以及空白字符都会导致解码失败。
func DecodeRawURL(s string) ([]byte, error) {
2023-12-27 19:00:14 +08:00
decoded, err := base64.RawURLEncoding.DecodeString(s)
2026-09-30 15:49:12 +08:00
if err != nil {
return nil, fmt.Errorf("URL 安全无填充 Base64 解码失败: %w", err)
}
return decoded, nil
2023-12-27 19:00:14 +08:00
}