How to get the MD5 hex hash for a file using VBA?
34,851
An older question that could use a better answer. These functions are specifically for hashing files, not for hashing passwords. As a bonus, I'm including a function for SHA1. If you get rid of the type declarations these functions work in VBScript too except that the GetFileBytes function needs to be changed to use FileSystemObject (or possibly ADO Stream) as the Free File doesn't exist in VBScript.
Private Sub TestMD5()
Debug.Print FileToMD5Hex("C:\test.txt")
Debug.Print FileToSHA1Hex("C:\test.txt")
End Sub
Public Function FileToMD5Hex(sFileName As String) As String
Dim enc
Dim bytes
Dim outstr As String
Dim pos As Integer
Set enc = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider")
'Convert the string to a byte array and hash it
bytes = GetFileBytes(sFileName)
bytes = enc.ComputeHash_2((bytes))
'Convert the byte array to a hex string
For pos = 1 To LenB(bytes)
outstr = outstr & LCase(Right("0" & Hex(AscB(MidB(bytes, pos, 1))), 2))
Next
FileToMD5Hex = outstr
Set enc = Nothing
End Function
Public Function FileToSHA1Hex(sFileName As String) As String
Dim enc
Dim bytes
Dim outstr As String
Dim pos As Integer
Set enc = CreateObject("System.Security.Cryptography.SHA1CryptoServiceProvider")
'Convert the string to a byte array and hash it
bytes = GetFileBytes(sFileName)
bytes = enc.ComputeHash_2((bytes))
'Convert the byte array to a hex string
For pos = 1 To LenB(bytes)
outstr = outstr & LCase(Right("0" & Hex(AscB(MidB(bytes, pos, 1))), 2))
Next
FileToSHA1Hex = outstr 'Returns a 40 byte/character hex string
Set enc = Nothing
End Function
Private Function GetFileBytes(ByVal path As String) As Byte()
Dim lngFileNum As Long
Dim bytRtnVal() As Byte
lngFileNum = FreeFile
If LenB(Dir(path)) Then ''// Does file exist?
Open path For Binary Access Read As lngFileNum
ReDim bytRtnVal(LOF(lngFileNum) - 1&) As Byte
Get lngFileNum, , bytRtnVal
Close lngFileNum
Else
Err.Raise 53
End If
GetFileBytes = bytRtnVal
Erase bytRtnVal
End Function
Comments
-
aF. almost 2 years
How can I get the MD5 hex hash for a file using VBA?
I need a version that works for a file.
Something as simple as this Python code:
import hashlib def md5_for_file(fileLocation, block_size=2**20): f = open(fileLocation) md5 = hashlib.md5() while True: data = f.read(block_size) if not data: break md5.update(data) f.close() return md5.hexdigest()
But in VBA.
-
Ben almost 12 yearsHuh? First, that's VB.NET not VBA and second, you're omitting some very important Import commands.
-
Michael Zlatkovsky - Microsoft almost 12 yearsOops, I had mis-read VBA as VB.NET. VBA would be a fair bit harder, since it does not have all of the .NET framework support that makes the above code so simple. As for imports, Visual Studio will probably suggest those for you automatically, but for completion's sake, they are System.IO and System.Security.Cryptography.
-
B Hart over 10 yearsQuick question: The variable "asc" for the UTF8Encoding isn't used anywhere, does this serve a purpose? Also, for it to work with VBScript you will have to probably open the file using an ADODB.Stream object instead of the FreeFile method... In any case Great share!
-
HK1 over 10 yearsI think the "asc" stuff must have been artifacts from when I was using this code to hash passwords. I've removed it now. And yes, Free File doesn't exist in VBScript. I did find a function that I think could be made to work that uses the File System Object: stackoverflow.com/questions/6060529/…
-
Nigel Heffernan over 6 yearsGood solution, with a couple of nits to pick...
Dim bytes() As Byte
offers a small gain; and passing it by reference into a reconfiguredPrivate Sub GetFileBytes(sFileName As String, arrBytes() As Byte)
means that you sidestep a redundant memory allocation - and that's a real gain, for resource usage and performance. The elephant in the room is that, for really large files,ReDim bytRtnVal(LOF(lngFileNum) - 1&) As Byte
will raise errors. But I can't post anything better, because I do not know of any 'chunking' or streaming API into the System.Security.Cryptography functions. -
Nigel Heffernan over 6 yearsUpdate: user Florent B. posted an answer with data passed in chunks to the MD5 hashing service in this StackOverflow answer