feat: add Base64 Raw support and smart decoding upgrade
This commit is contained in:
parent
5b4d5a8f3a
commit
47a62a3c16
@ -1,5 +1,13 @@
|
||||
# Changelog: @go/encoding
|
||||
|
||||
## [v1.1.0] - 2026-05-06
|
||||
|
||||
### Added
|
||||
- **Base64 无填充支持**:新增 `Base64Raw`、`Base64RawToString`、`UrlBase64Raw`、`UrlBase64RawToString` 接口,支持生成不带填充符(`=`)的编码。
|
||||
|
||||
### Changed
|
||||
- **智能解码升级**:升级了 `UnBase64` 与 `UnUrlBase64` 系列函数,通过 O(1) 零分配检测自动兼容“带填充”与“无填充”的输入数据,无需额外调用 Raw 解码接口。
|
||||
|
||||
## [v1.0.6] - 2026-05-06
|
||||
|
||||
### Changed
|
||||
|
||||
@ -18,9 +18,11 @@
|
||||
- `func Hex(data []byte) []byte` / `func HexToString(data []byte) string`
|
||||
- `func UnHex(data []byte) ([]byte, error)` / `func UnHexFromString(data string) ([]byte, error)`
|
||||
- `func Base64(data []byte) []byte` / `func Base64ToString(data []byte) string`
|
||||
- `func UnBase64(data []byte) ([]byte, error)` / `func UnBase64FromString(data string) ([]byte, error)`
|
||||
- `func Base64Raw(data []byte) []byte` / `func Base64RawToString(data []byte) string` (无填充版本)
|
||||
- `func UnBase64(data []byte) ([]byte, error)` / `func UnBase64FromString(data string) ([]byte, error)` (智能兼容填充与无填充)
|
||||
- `func UrlBase64(data []byte) []byte` / `func UrlBase64ToString(data []byte) string`
|
||||
- `func UnUrlBase64(data []byte) ([]byte, error)` / `func UnUrlBase64FromString(data string) ([]byte, error)`
|
||||
- `func UrlBase64Raw(data []byte) []byte` / `func UrlBase64RawToString(data []byte) string` (无填充版本)
|
||||
- `func UnUrlBase64(data []byte) ([]byte, error)` / `func UnUrlBase64FromString(data string) ([]byte, error)` (智能兼容填充与无填充)
|
||||
|
||||
### Web 编码 (URL/HTML)
|
||||
- `func UrlEncode(data []byte) string`
|
||||
|
||||
66
encoding.go
66
encoding.go
@ -44,6 +44,18 @@ func Base64ToString(data []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
// Base64Raw 将数据转换为无填充的 Base64 编码的字节切片
|
||||
func Base64Raw(data []byte) []byte {
|
||||
buf := make([]byte, base64.RawStdEncoding.EncodedLen(len(data)))
|
||||
base64.RawStdEncoding.Encode(buf, data)
|
||||
return buf
|
||||
}
|
||||
|
||||
// Base64RawToString 将数据转换为无填充的 Base64 编码的字符串
|
||||
func Base64RawToString(data []byte) string {
|
||||
return base64.RawStdEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
// UrlBase64 将数据转换为 URL 安全的 Base64 编码的字节切片
|
||||
func UrlBase64(data []byte) []byte {
|
||||
buf := make([]byte, base64.URLEncoding.EncodedLen(len(data)))
|
||||
@ -56,28 +68,56 @@ func UrlBase64ToString(data []byte) string {
|
||||
return base64.URLEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
// UnBase64 将 Base64 编码的字节切片解码
|
||||
// UrlBase64Raw 将数据转换为 URL 安全且无填充的 Base64 编码的字节切片
|
||||
func UrlBase64Raw(data []byte) []byte {
|
||||
buf := make([]byte, base64.RawURLEncoding.EncodedLen(len(data)))
|
||||
base64.RawURLEncoding.Encode(buf, data)
|
||||
return buf
|
||||
}
|
||||
|
||||
// UrlBase64RawToString 将数据转换为 URL 安全且无填充的 Base64 编码的字符串
|
||||
func UrlBase64RawToString(data []byte) string {
|
||||
return base64.RawURLEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
// UnBase64 将 Base64 编码的字节切片解码(自动兼容有无填充)
|
||||
func UnBase64(data []byte) ([]byte, error) {
|
||||
if len(data) > 0 && data[len(data)-1] == '=' {
|
||||
dbuf := make([]byte, base64.StdEncoding.DecodedLen(len(data)))
|
||||
n, err := base64.StdEncoding.Decode(dbuf, data)
|
||||
return dbuf[:n], err
|
||||
}
|
||||
|
||||
// UnBase64FromString 将 Base64 编码的字符串解码
|
||||
func UnBase64FromString(data string) ([]byte, error) {
|
||||
return base64.StdEncoding.DecodeString(data)
|
||||
}
|
||||
|
||||
// UnUrlBase64 将 URL 安全的 Base64 编码的字节切片解码
|
||||
func UnUrlBase64(data []byte) ([]byte, error) {
|
||||
dbuf := make([]byte, base64.URLEncoding.DecodedLen(len(data)))
|
||||
n, err := base64.URLEncoding.Decode(dbuf, data)
|
||||
}
|
||||
dbuf := make([]byte, base64.RawStdEncoding.DecodedLen(len(data)))
|
||||
n, err := base64.RawStdEncoding.Decode(dbuf, data)
|
||||
return dbuf[:n], err
|
||||
}
|
||||
|
||||
// UnUrlBase64FromString 将 URL 安全的 Base64 编码的字符串解码
|
||||
// UnBase64FromString 将 Base64 编码的字符串解码(自动兼容有无填充)
|
||||
func UnBase64FromString(data string) ([]byte, error) {
|
||||
if len(data) > 0 && data[len(data)-1] == '=' {
|
||||
return base64.StdEncoding.DecodeString(data)
|
||||
}
|
||||
return base64.RawStdEncoding.DecodeString(data)
|
||||
}
|
||||
|
||||
// UnUrlBase64 将 URL 安全的 Base64 编码的字节切片解码(自动兼容有无填充)
|
||||
func UnUrlBase64(data []byte) ([]byte, error) {
|
||||
if len(data) > 0 && data[len(data)-1] == '=' {
|
||||
dbuf := make([]byte, base64.URLEncoding.DecodedLen(len(data)))
|
||||
n, err := base64.URLEncoding.Decode(dbuf, data)
|
||||
return dbuf[:n], err
|
||||
}
|
||||
dbuf := make([]byte, base64.RawURLEncoding.DecodedLen(len(data)))
|
||||
n, err := base64.RawURLEncoding.Decode(dbuf, data)
|
||||
return dbuf[:n], err
|
||||
}
|
||||
|
||||
// UnUrlBase64FromString 将 URL 安全的 Base64 编码的字符串解码(自动兼容有无填充)
|
||||
func UnUrlBase64FromString(data string) ([]byte, error) {
|
||||
if len(data) > 0 && data[len(data)-1] == '=' {
|
||||
return base64.URLEncoding.DecodeString(data)
|
||||
}
|
||||
return base64.RawURLEncoding.DecodeString(data)
|
||||
}
|
||||
|
||||
// UrlEncode 对数据进行 URL 编码
|
||||
|
||||
@ -41,16 +41,37 @@ func TestBase64(t *testing.T) {
|
||||
t.Error("UnBase64FromString with cast.As failed")
|
||||
}
|
||||
|
||||
// Raw (Unpadded)
|
||||
rawEnc := encoding.Base64RawToString(data)
|
||||
if bytes.HasSuffix([]byte(rawEnc), []byte("=")) {
|
||||
t.Error("Base64Raw should not have padding")
|
||||
}
|
||||
rawDec, err := encoding.UnBase64FromString(rawEnc)
|
||||
if err != nil || !bytes.Equal(data, rawDec) {
|
||||
t.Error("Base64Raw smart decoding failed")
|
||||
}
|
||||
|
||||
// URL
|
||||
uEnc := encoding.UrlBase64ToString([]byte("hello/world+"))
|
||||
uData := []byte("hello/world+")
|
||||
uEnc := encoding.UrlBase64ToString(uData)
|
||||
uDec, _ := encoding.UnUrlBase64([]byte(uEnc))
|
||||
if !bytes.Equal([]byte("hello/world+"), uDec) {
|
||||
if !bytes.Equal(uData, uDec) {
|
||||
t.Error("UrlBase64 roundtrip failed")
|
||||
}
|
||||
|
||||
if !bytes.Equal(cast.As(encoding.UnUrlBase64FromString(uEnc)), []byte("hello/world+")) {
|
||||
if !bytes.Equal(cast.As(encoding.UnUrlBase64FromString(uEnc)), uData) {
|
||||
t.Error("UnUrlBase64FromString with cast.As failed")
|
||||
}
|
||||
|
||||
// URL Raw (Unpadded)
|
||||
uRawEnc := encoding.UrlBase64RawToString(uData)
|
||||
if bytes.HasSuffix([]byte(uRawEnc), []byte("=")) {
|
||||
t.Error("UrlBase64Raw should not have padding")
|
||||
}
|
||||
uRawDec, err := encoding.UnUrlBase64FromString(uRawEnc)
|
||||
if err != nil || !bytes.Equal(uData, uRawDec) {
|
||||
t.Error("UrlBase64Raw smart decoding failed")
|
||||
}
|
||||
}
|
||||
|
||||
// --- Web ---
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user