VBScript MD5Hash and IsHex Functions to Calculate MD5 File Hashes

Recently I was tasked with synchronizing directories between two different servers. Because files can change, become corrupted or otherwise altered without changing any of their attributes, it was pretty essential to ensure that these files were exactly the same.

There are a few utilities out there that can do this for you but one of the best suited is the security algorithm MD5. Well, obviously, VBScript does not have a built in MD5 summing function. There are some .NET libraries that do this pretty easily but unfortunately their methods are not exposed to VBScript (someone correct me if I’m wrong).

So to facilitate this MD5 summing I tried a couple of different methods. The first one, a pure VBScript solution, was functional. The first couple of files I tried it on seemed to go off without a hitch. That was, until I tried a 1.9MB file. That file took 59 minutes to run through the pure VBScript solution. Obviously this is totally impractical considering the size of some files.

The next method I tried was a compiled command line implementation of MD5. You’ll need to download this and make sure the “exe” is in the same directory as your VBS. This works great and is the method that I settled on. Hashing is quick, very quick. The same 1.9MB file happens well under a second. Several hundred meg files in just a second or two. Well within a reasonable margin. So here is the script and a quick example of usage:

sHash = MD5Hash("C:\config.sys")

Another side note, I wrote a “IsHash” function that returns true or false based on whether the string you pass is a valid hex value (since all MD5 hashes are returned as a hex string).

Public Function MD5Hash(sFileName)
  'This script is provided under the Creative Commons license located
  'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not
  'be used for commercial purposes with out the expressed written consent
  'of NateRice.com

  Const OpenAsDefault = -2
  Const FailIfNotExist = 0
  Const ForReading = 1
  
  Dim oMD5CmdShell, oMD5CmdFSO, sTemp, sTempFile, fMD5CmdFile, sPath
  Dim fResultsFile, sResults

  Set oMD5CmdShell = CreateObject("WScript.Shell")
  Set oMD5CmdFSO = CreateObject("Scripting.FileSystemObject")
  sTemp = oMD5CmdShell.ExpandEnvironmentStrings("%TEMP%")
  sTempFile = sTemp & "\" & oMD5CmdFSO.GetTempName
  
  '------Verify Input File Existance-----
  If Not oMD5CmdFSO.FileExists(sFileName) Then
    MD5Hash = "Failed: Invalid Input File."
  Else
    Set fMD5CmdFile = oMD5CmdFSO.GetFile(sFileName)
    sPath = fMD5CmdFile.ShortPath
    sFileName = sPath
    Set fMD5CmdFile = Nothing
  End If
  '--------------------------------------
  
  oMD5CmdShell.Run "%comspec% /c md5.exe -n " & sFileName & _
  " > " & sTempFile, 0, True

  Set fResultsFile = _
  oMD5CmdFSO.OpenTextFile(sTempFile, ForReading, FailIfNotExist, OpenAsDefault)
  sResults = fResultsFile.ReadAll
  sResults = trim(Replace(sResults, vbCRLF,""))
  fResultsFile.Close
  oMD5CmdFSO.DeleteFile sTempFile
  
  If len(sResults) = 32 And IsHex(sResults) Then
    MD5Hash = sResults
  Else
    MD5Hash = "Failed."
  End If
 
  Set oMD5CmdShell = Nothing
  Set oMD5CmdFSO = Nothing
End Function

Private Function IsHex(sHexCheck)
  'This script is provided under the Creative Commons license located
  'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not
  'be used for commercial purposes with out the expressed written consent
  'of NateRice.com

  Dim sX, bCharCheck, sHexValue, sHexValues, aHexValues
  sHexCheck = UCase(sHexCheck)
  sHexValues = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F"
  aHexValues = Split(sHexValues, ",")

  For sX = 1 To Len(sHexCheck)
    bCharCheck = False
    For Each sHexValue In aHexValues
      If UCase(Mid(sHexCheck,sX,1)) = sHexValue Then
        bCharCheck = True
        Exit For
      End If
    Next
    
    If bCharCheck <> True Then
      IsHex = False
      Exit Function
    End If
  Next
  
  IsHex = True
End Function

 

Leave a Comment