github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/codec/b64/base64.go (about) 1 package b64 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "io" 7 "strings" 8 ) 9 10 type EncodeFlags uint8 11 12 const ( 13 Std EncodeFlags = 1 << iota 14 URL 15 Raw 16 ) 17 18 // EncodeBytes2Bytes encodes src into base64 []byte. 19 func EncodeBytes2Bytes(src []byte, flags ...EncodeFlags) []byte { 20 var b bytes.Buffer 21 if _, err := Encode(&b, bytes.NewReader(src), flags...); err != nil { 22 panic(err) 23 } 24 return b.Bytes() 25 } 26 27 // EncodeString2String encodes src into base64 string. 28 func EncodeString2String(src string, flags ...EncodeFlags) string { 29 var b bytes.Buffer 30 if _, err := Encode(&b, strings.NewReader(src), flags...); err != nil { 31 panic(err) 32 } 33 return b.String() 34 } 35 36 // EncodeBytes2String encodes src into base64 []byte. 37 func EncodeBytes2String(src []byte, flags ...EncodeFlags) string { 38 var b bytes.Buffer 39 if _, err := Encode(&b, bytes.NewReader(src), flags...); err != nil { 40 panic(err) 41 } 42 return b.String() 43 } 44 45 // EncodeString2Bytes encodes src into base64 string. 46 func EncodeString2Bytes(src string, flags ...EncodeFlags) []byte { 47 var b bytes.Buffer 48 if _, err := Encode(&b, strings.NewReader(src), flags...); err != nil { 49 panic(err) 50 } 51 return b.Bytes() 52 } 53 54 // EncodeBytes encodes src into base64 []byte. 55 func EncodeBytes(src []byte, flags ...EncodeFlags) ([]byte, error) { 56 var b bytes.Buffer 57 if _, err := Encode(&b, bytes.NewReader(src), flags...); err != nil { 58 return nil, err 59 } 60 return b.Bytes(), nil 61 } 62 63 // EncodeString encodes src into base64 string. 64 func EncodeString(src string, flags ...EncodeFlags) (string, error) { 65 var b bytes.Buffer 66 if _, err := Encode(&b, strings.NewReader(src), flags...); err != nil { 67 return "", err 68 } 69 return b.String(), nil 70 } 71 72 type rawStdEncodingReader struct{ io.Reader } 73 74 // StdEncoding:RFC 4648 定义的标准 BASE64 编码字符集,结果填充=,使字节数为4的倍数 75 // URLEncoding:RFC 4648 定义的另一 BASE64 编码字符集,用 - 和 _ 替换了 + 和 /,用于URL和文件名,结果填充= 76 // RawStdEncoding:同 StdEncoding,但结果不填充= 77 // RawURLEncoding:同 URLEncoding,但结果不填充= 78 func (f *rawStdEncodingReader) Read(p []byte) (int, error) { 79 n, err := f.Reader.Read(p) 80 for i := 0; i < n; i++ { 81 switch p[i] { 82 case '-': 83 p[i] = '+' 84 case '_': 85 p[i] = '/' 86 case '=': 87 n = i 88 break 89 } 90 } 91 92 return n, err 93 } 94 95 // DecodeBytes2String decode bytes which is in base64 format ( any one of StdEncoding/URLEncoding/RawStdEncoding/RawURLEncoding). 96 func DecodeBytes2String(src []byte) string { 97 var b bytes.Buffer 98 if _, err := Decode(&b, bytes.NewReader(src)); err != nil { 99 panic(err) 100 } 101 return b.String() 102 } 103 104 // DecodeBytes2Bytes decode bytes which is in base64 format ( any one of StdEncoding/URLEncoding/RawStdEncoding/RawURLEncoding). 105 func DecodeBytes2Bytes(src []byte) []byte { 106 var b bytes.Buffer 107 if _, err := Decode(&b, bytes.NewReader(src)); err != nil { 108 panic(err) 109 } 110 return b.Bytes() 111 } 112 113 // DecodeString2String decode string which is in base64 format ( any one of StdEncoding/URLEncoding/RawStdEncoding/RawURLEncoding). 114 func DecodeString2String(src string) string { 115 var b bytes.Buffer 116 if _, err := Decode(&b, strings.NewReader(src)); err != nil { 117 panic(err) 118 } 119 return b.String() 120 } 121 122 // DecodeString2Bytes decode string which is in base64 format ( any one of StdEncoding/URLEncoding/RawStdEncoding/RawURLEncoding). 123 func DecodeString2Bytes(src string) []byte { 124 var b bytes.Buffer 125 if _, err := Decode(&b, strings.NewReader(src)); err != nil { 126 panic(err) 127 } 128 return b.Bytes() 129 } 130 131 // DecodeBytes decode bytes which is in base64 format ( any one of StdEncoding/URLEncoding/RawStdEncoding/RawURLEncoding). 132 func DecodeBytes(src []byte) ([]byte, error) { 133 var b bytes.Buffer 134 if _, err := Decode(&b, bytes.NewReader(src)); err != nil { 135 return nil, err 136 } 137 return b.Bytes(), nil 138 } 139 140 // DecodeString decode string which is in base64 format ( any one of StdEncoding/URLEncoding/RawStdEncoding/RawURLEncoding). 141 func DecodeString(src string) (string, error) { 142 var b bytes.Buffer 143 if _, err := Decode(&b, strings.NewReader(src)); err != nil { 144 return "", err 145 } 146 return b.String(), nil 147 } 148 149 // Decode copies io.Reader which is in base64 format ( any one of StdEncoding/URLEncoding/RawStdEncoding/RawURLEncoding). 150 func Decode(dst io.Writer, src io.Reader) (int64, error) { 151 return io.Copy(dst, base64.NewDecoder(base64.RawStdEncoding, &rawStdEncodingReader{Reader: src})) 152 } 153 154 // Encode copies io.Reader to io.Writer which is in base64 format ( any one of StdEncoding/URLEncoding/RawStdEncoding/RawURLEncoding). 155 func Encode(dst io.Writer, src io.Reader, flags ...EncodeFlags) (int64, error) { 156 enc := base64.StdEncoding 157 var flag EncodeFlags 158 for _, f := range flags { 159 flag |= f 160 } 161 162 if (flag&URL) == URL && (flag&Raw) == Raw { 163 enc = base64.RawURLEncoding 164 } else if (flag&Std) == Std && (flag&Raw) == Raw { 165 enc = base64.RawStdEncoding 166 } else if (flag & URL) == URL { 167 enc = base64.URLEncoding 168 } else { 169 enc = base64.StdEncoding 170 } 171 172 closer := base64.NewEncoder(enc, dst) 173 defer closer.Close() 174 return io.Copy(closer, src) 175 }