base64.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // based on https://github.com/powturbo/Turbo-Base64
  2. package yu_base64
  3. import yu_fast "gogs.qqck.cn/s/tools/fast"
  4. type Encoding struct {
  5. lutSe [64]byte
  6. lutXe [4096]uint32
  7. lutXd0 [256]uint32
  8. lutXd1 [256]uint32
  9. lutXd2 [256]uint32
  10. lutXd3 [256]uint32
  11. pad bool
  12. }
  13. func (e *Encoding) EncodedLen(n int) int {
  14. if !e.pad {
  15. return (n*8 + 5) / 6
  16. }
  17. return (n + 2) / 3 * 4
  18. }
  19. func (e *Encoding) Encode(src []byte) []byte {
  20. if len(src) == 0 {
  21. return []byte{}
  22. }
  23. length := e.EncodedLen(len(src))
  24. dst := make([]byte, length)
  25. e.encode(dst, src, uintptr(length))
  26. return dst
  27. }
  28. func (e *Encoding) EncodeS(src string) []byte {
  29. return e.Encode(yu_fast.S2B(src))
  30. }
  31. func (e *Encoding) Encode2S(src []byte) string {
  32. return string(e.Encode(src))
  33. }
  34. func (e *Encoding) EncodeS2S(src string) string {
  35. return string(e.Encode(yu_fast.S2B(src)))
  36. }
  37. func (e *Encoding) DecodedLen(n int) int {
  38. sf := 0
  39. if n > 4 {
  40. sf++
  41. }
  42. if !e.pad {
  43. return n*6/8 + sf
  44. }
  45. return n/4*3 + sf
  46. }
  47. func (e *Encoding) Decode(src []byte) []byte {
  48. if len(src) == 0 {
  49. return []byte{}
  50. }
  51. length := e.DecodedLen(len(src))
  52. if length == 0 {
  53. return []byte{}
  54. }
  55. dst := make([]byte, length)
  56. return dst[:e.decode(dst, src)]
  57. }
  58. func (e *Encoding) DecodeS(src string) []byte {
  59. return e.Decode(yu_fast.S2B(src))
  60. }
  61. func (e *Encoding) Decode2S(src []byte) string {
  62. return string(e.Decode(src))
  63. }
  64. func (e *Encoding) DecodeS2S(src string) string {
  65. return string(e.Decode(yu_fast.S2B(src)))
  66. }
  67. func NewEncoding(lutSe [64]byte, pad bool) *Encoding {
  68. lutXe, lutXd0, lutXd1, lutXd2, lutXd3 := makeLuts(lutSe)
  69. return &Encoding{
  70. lutSe: lutSe,
  71. lutXe: lutXe,
  72. lutXd0: lutXd0,
  73. lutXd1: lutXd1,
  74. lutXd2: lutXd2,
  75. lutXd3: lutXd3,
  76. pad: pad,
  77. }
  78. }
  79. var (
  80. Std = NewEncoding(stdLutSe, true)
  81. RawStd = NewEncoding(stdLutSe, false)
  82. URL = NewEncoding(urlLutSe, true)
  83. RawURL = NewEncoding(urlLutSe, false)
  84. )