Sunday, 26 November 2017

Use MSXML2 to encode bytes or String to Base64

So I want to be able to decode and encode a byte array to and from base64. A canonical answer is given at SO (thanks!) but it converts to and from strings; the byte array element is buried in the code. I would like the option to pass byte arrays and so I have rearranged the code to make this more explicit. Also we use StrConv instead of the ADO.Stream trick. Here is my version.


Option Explicit
Option Private Module

'* Tools->References
'* Microsoft XML, v6.0


'* External Docs
'* MSDN - How to Encode XML Data  - https://msdn.microsoft.com/en-us/library/aa468560.aspx
'* MSDN - nodeTypedValue Property - https://msdn.microsoft.com/en-us/library/ms762308(v=vs.85).aspx
'* SO - Base64 Encode String in VBScript - https://stackoverflow.com/questions/496751/base64-encode-string-in-vbscript#answer-506992

Private Sub TestBase64Encode()
    Dim sOriginal As String
    sOriginal = "Hello world"
    
    Dim sBase64 As String
    sBase64 = Base64EncodeString(sOriginal)
    
    Dim sDecoded As String
    sDecoded = Base64DecodeString(sBase64)
    
    Debug.Assert sOriginal = sDecoded

End Sub


Function Base64EncodeString(ByVal sText As String) As String
    Dim byt() As Byte
    
    byt = VBA.StrConv(sText, VbStrConv.vbFromUnicode, 1033)
    
    Base64EncodeString = Base64EncodeFromBytes(byt)
End Function



Function Base64EncodeFromBytes(ByRef byt() As Byte) As String

    Dim oXML  As MSXML2.DOMDocument60
    Set oXML = New MSXML2.DOMDocument60
    
    Dim oNode As MSXML2.IXMLDOMNode

    Set oNode = oXML.createElement("base64")
    oNode.DataType = "bin.base64"
    
    oNode.nodeTypedValue = byt
    Base64EncodeFromBytes = oNode.Text
    
    Debug.Assert TypeName(Base64EncodeFromBytes) = "String"
    Set oNode = Nothing
    Set oXML = Nothing
End Function


Function Base64DecodeString(ByVal sText As String) As String

    Dim byt() As Byte
    byt = Base64DecodeToBytes(sText)
    

    Base64DecodeString = VBA.StrConv(byt(), VbStrConv.vbUnicode, 1033)

End Function

Function Base64DecodeToBytes(ByVal sEncoded As String) As Byte()
    
    Debug.Assert TypeName(sEncoded) = "String"
    
    Dim oXML  As MSXML2.DOMDocument60
    Set oXML = New MSXML2.DOMDocument60
    
    Dim oNode As MSXML2.IXMLDOMNode
    Set oNode = oXML.createElement("base64")
    
    oNode.DataType = "bin.base64"
    oNode.Text = sEncoded
    
    Base64DecodeToBytes = oNode.nodeTypedValue
    
    Set oNode = Nothing
    Set oXML = Nothing
End Function


No comments:

Post a Comment