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