// based on https://github.com/powturbo/Turbo-Base64 package yu_base64 import yu_fast "gogs.qqck.cn/s/tools/fast" type Encoding struct { lutSe [64]byte lutXe [4096]uint32 lutXd0 [256]uint32 lutXd1 [256]uint32 lutXd2 [256]uint32 lutXd3 [256]uint32 pad bool } func (e *Encoding) EncodedLen(n int) int { if !e.pad { return (n*8 + 5) / 6 } return (n + 2) / 3 * 4 } func (e *Encoding) Encode(src []byte) []byte { if len(src) == 0 { return []byte{} } length := e.EncodedLen(len(src)) dst := make([]byte, length) e.encode(dst, src, uintptr(length)) return dst } func (e *Encoding) EncodeS(src string) []byte { return e.Encode(yu_fast.S2B(src)) } func (e *Encoding) Encode2S(src []byte) string { return string(e.Encode(src)) } func (e *Encoding) EncodeS2S(src string) string { return string(e.Encode(yu_fast.S2B(src))) } func (e *Encoding) DecodedLen(n int) int { sf := 0 if n > 4 { sf++ } if !e.pad { return n*6/8 + sf } return n/4*3 + sf } func (e *Encoding) Decode(src []byte) []byte { if len(src) == 0 { return []byte{} } length := e.DecodedLen(len(src)) if length == 0 { return []byte{} } dst := make([]byte, length) return dst[:e.decode(dst, src)] } func (e *Encoding) DecodeS(src string) []byte { return e.Decode(yu_fast.S2B(src)) } func (e *Encoding) Decode2S(src []byte) string { return string(e.Decode(src)) } func (e *Encoding) DecodeS2S(src string) string { return string(e.Decode(yu_fast.S2B(src))) } func NewEncoding(lutSe [64]byte, pad bool) *Encoding { lutXe, lutXd0, lutXd1, lutXd2, lutXd3 := makeLuts(lutSe) return &Encoding{ lutSe: lutSe, lutXe: lutXe, lutXd0: lutXd0, lutXd1: lutXd1, lutXd2: lutXd2, lutXd3: lutXd3, pad: pad, } } var ( Std = NewEncoding(stdLutSe, true) RawStd = NewEncoding(stdLutSe, false) URL = NewEncoding(urlLutSe, true) RawURL = NewEncoding(urlLutSe, false) )