// 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 }