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  }