VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "clsBase64"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Private Const MAX_LINELENGTH As Long = 1000
Private Const CHAR_EQUAL As Byte = 61
Private Const CHAR_CR As Byte = 13
Private Const CHAR_LF As Byte = 10
Private m_Index1(0 To 255) As Byte
Private m_Index2(0 To 255) As Byte
Private m_Index3(0 To 255) As Byte
Private m_Index4(0 To 63) As Byte
Private m_ReverseIndex1(0 To 255) As Byte
Private m_ReverseIndex2(0 To 255, 0 To 1) As Byte
Private m_ReverseIndex3(0 To 255, 0 To 1) As Byte
Private m_ReverseIndex4(0 To 255) As Byte
Public Function Encode(sInput As String) As String
On Error GoTo Ending
Dim bTemp() As Byte
bTemp = StrConv(sInput, vbFromUnicode)
Encode = StrConv(EncodeArr(bTemp), vbUnicode)
Exit Function
Ending:
    Encode = vbNS
End Function
Public Function Decode(sInput As String) As String
On Error GoTo Ending
Dim bTemp() As Byte
bTemp = StrConv(sInput, vbFromUnicode)
Decode = StrConv(DecodeArr(bTemp), vbUnicode)
Exit Function
Ending:
    Decode = vbNS
End Function
Private Function EncodeArr(bInput() As Byte) As Byte()
On Error Resume Next
Dim bOutput() As Byte
Dim K As Long
Dim L As Long
Dim i As Long
Dim evenBound As Long
Dim CurrentOut As Long
Dim B As Byte
Dim C As Byte
Dim d As Byte
Dim linelength As Long
K = LBound(bInput)
L = UBound(bInput)
i = L - K + 1
   Select Case i Mod 3
      Case 0:
         i = (i \ 3) * 4
         evenBound = L
      Case 1:
         i = ((i \ 3) * 4) + 4
         evenBound = L - 1
      Case 2:
         i = ((i \ 3) * 4) + 4
         evenBound = L - 2
      Case 3:
         i = ((i \ 3) * 4) + 4
         evenBound = L - 3
   End Select
   If i Mod MAX_LINELENGTH = 0 Then
      i = i + (i \ MAX_LINELENGTH) * 2 - 2
   Else
      i = i + (i \ MAX_LINELENGTH) * 2
   End If
   ReDim bOutput(0 To i - 1)
    
   CurrentOut = 0
   linelength = 0

   For i = K To evenBound Step 3
      B = bInput(i)
      C = bInput(i + 1)
      d = bInput(i + 2)
      bOutput(CurrentOut) = m_Index1(B And &HFC)
      bOutput(CurrentOut + 1) = m_Index2((B And &H3) Or (C And &HF0))
      bOutput(CurrentOut + 2) = m_Index3((C And &HF) Or (d And &HC0))
      bOutput(CurrentOut + 3) = m_Index4(d And &H3F)
      CurrentOut = CurrentOut + 4
      linelength = linelength + 4
      
      If linelength >= MAX_LINELENGTH Then
         If i <> L - 2 Then
            bOutput(CurrentOut) = CHAR_CR
            bOutput(CurrentOut + 1) = CHAR_LF
         End If
         CurrentOut = CurrentOut + 2
         linelength = 0
      End If
   Next i
   
   Select Case L - i
      Case 1:
         B = bInput(i)
         C = bInput(i + 1)
         d = 0
         bOutput(CurrentOut) = m_Index1(B And &HFC)
         bOutput(CurrentOut + 1) = m_Index2((B And &H3) Or (C And &HF0))
         bOutput(CurrentOut + 2) = m_Index3((C And &HF) Or (d And &HC0))
         bOutput(CurrentOut + 3) = CHAR_EQUAL
         CurrentOut = CurrentOut + 4
         linelength = linelength + 4
      Case 0:
         B = bInput(i)
         C = 0
         bOutput(CurrentOut) = m_Index1(B And &HFC)
         bOutput(CurrentOut + 1) = m_Index2((B And &H3) Or (C And &HF0))
         bOutput(CurrentOut + 2) = CHAR_EQUAL
         bOutput(CurrentOut + 3) = CHAR_EQUAL
         CurrentOut = CurrentOut + 4
         linelength = linelength + 4
   End Select
   
   EncodeArr = bOutput
End Function
Private Function DecodeArr(bInput() As Byte) As Byte()
   On Error Resume Next
   
   Dim bOutput() As Byte
   Dim OutLength As Long
   Dim CurrentOut As Long
   Dim K As Long
   Dim L As Long
   Dim i As Long
   Dim J As Long
   Dim B As Byte
   Dim C As Byte
   Dim d As Byte
   Dim E As Byte
   
   K = LBound(bInput)
   L = UBound(bInput)
   i = L - K + 1
   J = i Mod (MAX_LINELENGTH + 2)
   If J = 0 Then
      OutLength = (i \ (MAX_LINELENGTH + 2)) * (MAX_LINELENGTH \ 4) * 3
   Else
      J = (J / 4) * 3
      If bInput(L) = CHAR_EQUAL Then J = J - 1
      If bInput(L - 1) = CHAR_EQUAL Then J = J - 1
      OutLength = (i \ (MAX_LINELENGTH + 2)) * (MAX_LINELENGTH \ 4) * 3 + J
   End If
   ReDim bOutput(0 To OutLength - 1)
   
   CurrentOut = 0
   
   For i = K To L
      Select Case bInput(i)
         Case CHAR_CR
            'Do nothing
         Case CHAR_LF
            'Do nothing
         Case Else
            If L - i >= 3 Then
               B = bInput(i)
               C = bInput(i + 1)
               d = bInput(i + 2)
               E = bInput(i + 3)
               
               If E <> CHAR_EQUAL Then
                  bOutput(CurrentOut) = m_ReverseIndex1(B) Or m_ReverseIndex2(C, 0)
                  bOutput(CurrentOut + 1) = m_ReverseIndex2(C, 1) Or m_ReverseIndex3(d, 0)
                  bOutput(CurrentOut + 2) = m_ReverseIndex3(d, 1) Or m_ReverseIndex4(E)
                  CurrentOut = CurrentOut + 3
                  i = i + 3
               ElseIf d <> CHAR_EQUAL Then
                  bOutput(CurrentOut) = m_ReverseIndex1(B) Or m_ReverseIndex2(C, 0)
                  bOutput(CurrentOut + 1) = m_ReverseIndex2(C, 1) Or m_ReverseIndex3(d, 0)
                  CurrentOut = CurrentOut + 2
                  i = i + 3
               Else
                  bOutput(CurrentOut) = m_ReverseIndex1(B) Or m_ReverseIndex2(C, 0)
                  CurrentOut = CurrentOut + 1
                  i = i + 3
               End If
               
            Else
            End If
      End Select
   Next i
   If OutLength <> CurrentOut + 1 Then
      ReDim Preserve bOutput(0 To CurrentOut - 1)
   End If
   
   DecodeArr = bOutput
End Function
Private Sub Class_Initialize()
   Dim i As Long
   m_Index4(0) = 65
   m_Index4(1) = 66
   m_Index4(2) = 67
   m_Index4(3) = 68
   m_Index4(4) = 69
   m_Index4(5) = 70
   m_Index4(6) = 71
   m_Index4(7) = 72
   m_Index4(8) = 73
   m_Index4(9) = 74
   m_Index4(10) = 75
   m_Index4(11) = 76
   m_Index4(12) = 77
   m_Index4(13) = 78
   m_Index4(14) = 79
   m_Index4(15) = 80
   m_Index4(16) = 81
   m_Index4(17) = 82
   m_Index4(18) = 83
   m_Index4(19) = 84
   m_Index4(20) = 85
   m_Index4(21) = 86
   m_Index4(22) = 87
   m_Index4(23) = 88
   m_Index4(24) = 89
   m_Index4(25) = 90
   m_Index4(26) = 97
   m_Index4(27) = 98
   m_Index4(28) = 99
   m_Index4(29) = 100
   m_Index4(30) = 101
   m_Index4(31) = 102
   m_Index4(32) = 103
   m_Index4(33) = 104
   m_Index4(34) = 105
   m_Index4(35) = 106
   m_Index4(36) = 107
   m_Index4(37) = 108
   m_Index4(38) = 109
   m_Index4(39) = 110
   m_Index4(40) = 111
   m_Index4(41) = 112
   m_Index4(42) = 113
   m_Index4(43) = 114
   m_Index4(44) = 115
   m_Index4(45) = 116
   m_Index4(46) = 117
   m_Index4(47) = 118
   m_Index4(48) = 119
   m_Index4(49) = 120
   m_Index4(50) = 121
   m_Index4(51) = 122
   m_Index4(52) = 48
   m_Index4(53) = 49
   m_Index4(54) = 50
   m_Index4(55) = 51
   m_Index4(56) = 52
   m_Index4(57) = 53
   m_Index4(58) = 54
   m_Index4(59) = 55
   m_Index4(60) = 56
   m_Index4(61) = 57
   m_Index4(62) = 43
   m_Index4(63) = 47
   For i = 0 To 63
      m_Index1((i * 4) And &HFC) = m_Index4(i)
      m_Index2(((i And &HF) * 16) Or ((i And &H30) \ 16)) = m_Index4(i)
      m_Index3((i \ 4 And &HF) Or ((i And &H3) * 64)) = m_Index4(i)
   Next i
     
   m_ReverseIndex4(65) = 0
   m_ReverseIndex4(66) = 1
   m_ReverseIndex4(67) = 2
   m_ReverseIndex4(68) = 3
   m_ReverseIndex4(69) = 4
   m_ReverseIndex4(70) = 5
   m_ReverseIndex4(71) = 6
   m_ReverseIndex4(72) = 7
   m_ReverseIndex4(73) = 8
   m_ReverseIndex4(74) = 9
   m_ReverseIndex4(75) = 10
   m_ReverseIndex4(76) = 11
   m_ReverseIndex4(77) = 12
   m_ReverseIndex4(78) = 13
   m_ReverseIndex4(79) = 14
   m_ReverseIndex4(80) = 15
   m_ReverseIndex4(81) = 16
   m_ReverseIndex4(82) = 17
   m_ReverseIndex4(83) = 18
   m_ReverseIndex4(84) = 19
   m_ReverseIndex4(85) = 20
   m_ReverseIndex4(86) = 21
   m_ReverseIndex4(87) = 22
   m_ReverseIndex4(88) = 23
   m_ReverseIndex4(89) = 24
   m_ReverseIndex4(90) = 25
   m_ReverseIndex4(97) = 26
   m_ReverseIndex4(98) = 27
   m_ReverseIndex4(99) = 28
   m_ReverseIndex4(100) = 29
   m_ReverseIndex4(101) = 30
   m_ReverseIndex4(102) = 31
   m_ReverseIndex4(103) = 32
   m_ReverseIndex4(104) = 33
   m_ReverseIndex4(105) = 34
   m_ReverseIndex4(106) = 35
   m_ReverseIndex4(107) = 36
   m_ReverseIndex4(108) = 37
   m_ReverseIndex4(109) = 38
   m_ReverseIndex4(110) = 39
   m_ReverseIndex4(111) = 40
   m_ReverseIndex4(112) = 41
   m_ReverseIndex4(113) = 42
   m_ReverseIndex4(114) = 43
   m_ReverseIndex4(115) = 44
   m_ReverseIndex4(116) = 45
   m_ReverseIndex4(117) = 46
   m_ReverseIndex4(118) = 47
   m_ReverseIndex4(119) = 48
   m_ReverseIndex4(120) = 49
   m_ReverseIndex4(121) = 50
   m_ReverseIndex4(122) = 51
   m_ReverseIndex4(48) = 52
   m_ReverseIndex4(49) = 53
   m_ReverseIndex4(50) = 54
   m_ReverseIndex4(51) = 55
   m_ReverseIndex4(52) = 56
   m_ReverseIndex4(53) = 57
   m_ReverseIndex4(54) = 58
   m_ReverseIndex4(55) = 59
   m_ReverseIndex4(56) = 60
   m_ReverseIndex4(57) = 61
   m_ReverseIndex4(43) = 62
   m_ReverseIndex4(47) = 63
   For i = 0 To 255
      If m_ReverseIndex4(i) <> 0 Then
         m_ReverseIndex1(i) = m_ReverseIndex4(i) * 4
         
         m_ReverseIndex2(i, 0) = m_ReverseIndex4(i) \ 16
         m_ReverseIndex2(i, 1) = (m_ReverseIndex4(i) And &HF) * 16
         
         m_ReverseIndex3(i, 0) = m_ReverseIndex4(i) \ 4
         m_ReverseIndex3(i, 1) = (m_ReverseIndex4(i) And &H3) * 64
      End If
   Next i
End Sub

