Files
encryptx/base64x/base64x.go
T
2026-09-30 15:49:12 +08:00

150 lines
5.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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,
// 需要限制输入大小以防内存放大类拒绝服务。
package base64x
import (
"encoding/base64"
"fmt"
)
// Encode 使用标准 Base64 字母表(+/)编码数据,输出带 = 填充。
//
// 参数:
// - data: 待编码的字节串,可以为 nil(返回空字符串)。
//
// 返回值:标准 Base64 字符串,长度总是 4 的倍数。
//
// 安全注意:Base64 不提供机密性;且标准字母表含 + 与 /,
// 不要直接用于 URL 或文件名,请使用 EncodeURL 或 EncodeRawURL。
func Encode(data []byte) string {
return base64.StdEncoding.EncodeToString(data)
}
// Decode 解码标准 Base64 字符串(要求带正确的 = 填充)。
//
// 参数:
// - s: 待解码的标准 Base64 字符串。
//
// 返回值:解码后的字节串;失败时返回 nil 与包装后的 error。
//
// 安全注意:失败时不会返回任何部分解码结果,避免调用方误用不完整数据;
// 解码结果可能很长,处理不可信输入前应限制输入长度。
func Decode(s string) ([]byte, error) {
decoded, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return nil, fmt.Errorf("标准 Base64 解码失败: %w", err)
}
return decoded, nil
}
// EncodeURL 使用 URL/文件名安全字母表(-_)编码数据,输出带 = 填充。
//
// 参数:
// - data: 待编码的字节串,可以为 nil(返回空字符串)。
//
// 返回值:URL 安全 Base64 字符串,长度总是 4 的倍数。
//
// 安全注意:字母表不含 + 与 /,可安全用于 URL 与文件名;
// 但 = 填充在某些上下文仍需转义,若需彻底避免请使用 EncodeRawURL。
func EncodeURL(data []byte) string {
return base64.URLEncoding.EncodeToString(data)
}
// DecodeURL 解码 URL 安全 Base64 字符串(要求带正确的 = 填充)。
//
// 参数:
// - s: 待解码的 URL 安全 Base64 字符串。
//
// 返回值:解码后的字节串;失败时返回 nil 与包装后的 error。
//
// 安全注意:失败时不会返回部分结果;本函数不接受标准字母表中的 + 与 /。
func DecodeURL(s string) ([]byte, error) {
decoded, err := base64.URLEncoding.DecodeString(s)
if err != nil {
return nil, fmt.Errorf("URL 安全 Base64 解码失败: %w", err)
}
return decoded, nil
}
// EncodeRaw 使用标准 Base64 字母表(+/)编码数据,输出**不带** = 填充。
//
// 参数:
// - data: 待编码的字节串,可以为 nil(返回空字符串)。
//
// 返回值:无填充的标准 Base64 字符串,长度不再保证是 4 的倍数。
//
// 安全注意:无填充版本更适合放进 JSON、定长字段;但字母表仍含 + 与 /,
// 不要直接用于 URL 或文件名。
func EncodeRaw(data []byte) string {
return base64.RawStdEncoding.EncodeToString(data)
}
// DecodeRaw 解码无填充的标准 Base64 字符串。
//
// 参数:
// - s: 待解码的无填充标准 Base64 字符串。
//
// 返回值:解码后的字节串;失败时返回 nil 与包装后的 error。
//
// 安全注意:失败时不会返回部分结果;带 = 填充的输入会被拒绝。
func DecodeRaw(s string) ([]byte, error) {
decoded, err := base64.RawStdEncoding.DecodeString(s)
if err != nil {
return nil, fmt.Errorf("无填充标准 Base64 解码失败: %w", err)
}
return decoded, nil
}
// EncodeRawURL 使用 URL/文件名安全字母表(-_)编码数据,输出**不带** = 填充。
//
// 参数:
// - data: 待编码的字节串,可以为 nil(返回空字符串)。
//
// 返回值:URL 安全且无填充的 Base64 字符串,可直接放进 URL 路径、
// 查询串、文件名与 JSON 字符串。
//
// 安全注意:这是本包适用面最广的编码,但仍然只是编码:
// 若数据是秘密,必须先加密(例如 AES-GCM)后再编码。
func EncodeRawURL(data []byte) string {
return base64.RawURLEncoding.EncodeToString(data)
}
// DecodeRawURL 解码 URL 安全且无填充的 Base64 字符串。
//
// 参数:
// - s: 待解码的 URL 安全无填充 Base64 字符串。
//
// 返回值:解码后的字节串;失败时返回 nil 与包装后的 error。
//
// 安全注意:失败时不会返回部分结果;输入中的 = 填充、
// +、/ 以及空白字符都会导致解码失败。
func DecodeRawURL(s string) ([]byte, error) {
decoded, err := base64.RawURLEncoding.DecodeString(s)
if err != nil {
return nil, fmt.Errorf("URL 安全无填充 Base64 解码失败: %w", err)
}
return decoded, nil
}