Friday, 10 July 2009

Calculating an IRMark for the HMRC Gateway using VB.NET

This took ages to finally work out so I thought I'd share the function. Just pass in the XML file as a Byte Array and the IRMark is returned.

Friend Shared Function GetIRMark(ByVal Xml As Byte()) As String

' Convert Byte array to string
Dim text As String = Encoding.UTF8.GetString(Xml)
Dim Doc As New XmlDocument Doc.PreserveWhitespace = True Doc.LoadXml(text)
Dim ns As New XmlNamespaceManager(Doc.NameTable) ns.AddNamespace("env", Doc.DocumentElement.NamespaceURI)
Dim Body = Doc.SelectSingleNode("//env:Body", ns) ns.AddNamespace("tax", Body.FirstChild.NextSibling.NamespaceURI)

Create an XML document of just the body section
Dim xmlBody = New XmlDocument
xmlBody.PreserveWhitespace = True
xmlBody.LoadXml(Body.OuterXml)

' Remove any existing IRMark
Dim nodeIr = xmlBody.SelectSingleNode("//tax:IRmark", ns)
If Not nodeIr Is Nothing Then
nodeIr.ParentNode.RemoveChild(nodeIr)
End If

' Normalise the document using C14N (Canonicalisation)
Dim c14n = New XmlDsigC14NTransform c14n.LoadInput(xmlBody)

Using S As Stream = c14n.GetOutput()
Dim Buffer(S.Length - 1) As Byte
S.Read(Buffer, 0, S.Length)

' Convert to string and normalise line endings
text = Encoding.UTF8.GetString(Buffer)
text = text.Replace("
", "")
text = text.Replace(vbCrLf, vbLf)
text = text.Replace(vbCr, vbLf)

' Convert the final document back into a byte array
Dim b = Encoding.UTF8.GetBytes(text)

' Create the SHA-1 hash from the final document
Dim SHA = SHA1.Create
Dim hash = SHA.ComputeHash(b)
Return Convert.ToBase64String(hash)
End Using

End Function

6 comments:

  1. Hi,

    Very interesting. I need to generate an irmark via VBA in Excel. Would it be possible to build this function into a dll file that could be accessed from the Excel COM application?

    ReplyDelete
  2. I guess so although it's years since I've done Office or VBA Development (everything seemed to break with each new version). It may need slight modification to use a string input instead of a byte array as I don't think VBA can produce a .NET Byte array although I could be wrong.

    ReplyDelete
  3. Thanks you save my life!
    I have been stucked for 5 days in this IRMark thing.

    ReplyDelete
  4. Fantastic bit of code - saved me many hours!

    ReplyDelete
  5. Thanks a lot for posting this. The c# version is available at http://neophytedeveloper.wordpress.com/asp-net-articles/hmrc-generating-irmark-c-net/ if anyone wants it.

    ReplyDelete
  6. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru Dot Net Training in Chennai. Nowadays Dot Net has tons of job opportunities on various vertical industry.
    or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

    ReplyDelete