UPDATE: it's now a Gist.
Today's useful snippet: Base64 encoding in VBA (not VB.NET; the latter has a builtin API for that).
Encodes an array of bytes into a string. Doesn't make any assumptions about the bounds of the source array. Processes the entire array; can be trivially modified to deal with a array slice.
Public Function ToBase64(Src() As Byte) As String
Const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Dim SrcLen As Long, i As Long, Remainder As Long
Dim RLen As Long, Triad As Long, LastSrcIndex As Long
SrcLen = UBound(Src) - LBound(Src) + 1
Remainder = SrcLen Mod 3
'Index of the first byte of the leftover 1- or 2-byte chunk
RLen = LBound(Src) + SrcLen - Remainder
LastSrcIndex = RLen - 3
ToBase64 = ""
'The 3 byte chunks of the block
For i = LBound(Src) To LastSrcIndex Step 3
Triad = (CLng(Src(i)) * &H10000) Or _
(CLng(Src(i + 1)) * &H100) Or Src(i + 2)
ToBase64 = ToBase64 & _
Mid(ALPHABET, ((Triad \ &H40000) And &H3F) + 1, 1) & _
Mid(ALPHABET, ((Triad \ &H1000) And &H3F) + 1, 1) & _
Mid(ALPHABET, ((Triad \ &H40) And &H3F) + 1, 1) & _
Mid(ALPHABET, (Triad And &H3F) + 1, 1)
Next
'The remainder, if any
If Remainder = 1 Then
ToBase64 = ToBase64 & _
Mid(ALPHABET, ((Src(RLen) \ 4) And &H3F) + 1, 1) & _
Mid(ALPHABET, ((Src(RLen) * &H10) And &H3F) + 1, 1) & "=="
ElseIf Remainder = 2 Then
Triad = (CLng(Src(RLen)) * &H100) Or Src(RLen + 1)
ToBase64 = ToBase64 & _
Mid(ALPHABET, ((Triad \ &H400) And &H3F) + 1, 1) & _
Mid(ALPHABET, ((Triad \ &H10) And &H3F) + 1, 1) & _
Mid(ALPHABET, ((Triad * 4) And &H3F) + 1, 1) & "="
End If
End Function
A useful variation would use a preallocated buffer for the encoded chunk, with assignment to Mid() instead of concatenation. When encoding large pieces (>100KB), it makes sense to save on string allocation and copying.
The formula for the length of a Base64-encoded string is: ((SourceLength + 2) \ 3) * 4.
No comments:
Post a Comment