VBA计算文件内容的MD5哈希

Posted

技术标签:

【中文标题】VBA计算文件内容的MD5哈希【英文标题】:VBA calculate MD5 hash on file contents 【发布时间】:2015-11-14 03:05:20 【问题描述】:

我需要一个 VBA 例程来计算文件内容的 MD5 哈希值。我找到了一些示例(例如,here),但我发现当文件名包含某些 Unicode 字符时它们会崩溃,因此我正在尝试调整代码以避免这种情况。

此代码不会导致错误,但也不会返回正确的 MD5 哈希值。怎么了?

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

Private Function GetFileBytes(path As String) As Byte()
    Dim fso As Object
    Set fso = CreateObject("scripting.FileSystemObject")

    Dim fil As Object
    Set fil = fso.GetFile(path)

'    Dim fpga As Variant
    GetFileBytes = fil.OpenAsTextStream().Read(fil.Size)

    Set fil = Nothing
    Set fso = Nothing
End Function

【问题讨论】:

【参考方案1】:

Scripting.FileSystemObject 无法像 TextStream 一样正确处理某些字符序列。

使用ADODB.Stream ActiveX 从文件中检索字节数组。它适用于文本和二进制类型的数据,还允许更改字符串的字符集(FSO 仅适用于 ASCII 和 Unicode,并且仅适用于文件)。

Function GetFileBytes(strPath As String) As Byte()
    With CreateObject("ADODB.Stream")
        .Type = 1 ' adTypeBinary
        .Open
        .LoadFromFile (strPath)
        GetFileBytes = .Read()
    End With
End Function

另一个处理二进制数据的 ActiveX 是SAPI.spFileStream。最显着的优势之一 - 它允许仅将文件的一部分加载到内存中(在某些情况下,当比较大文件时,它可以帮助大幅提高性能,按块检查 md5)。

Function GetFileBytes(strPath As String) As Byte()
    Dim arrContent As Variant
    With CreateObject("SAPI.spFileStream")
        .Open strPath, 0
        .Read arrContent, CreateObject("Scripting.FileSystemObject").GetFile(strPath).Size
        .Close
    End With
    GetFileBytes = arrContent
End Function

【讨论】:

不错的代码(从现在开始,我将使用 ADODB.Stream 而不是 Open #F for Binary Read` 和 Get)。 但是,缺少一个组件:您是否有一个 System.Security.Cryptography 函数将连续的字节块加载到单个哈希计算中的示例? 更新:用户 Florent B. 在this *** answer 中发布了一个答案,其中数据以块的形式传递给 MD5 哈希服务 - 这与您的 SAPI.spFileStream 实施非常有效。

以上是关于VBA计算文件内容的MD5哈希的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 VBA 获取文件的 MD5 十六进制哈希?

python 使用hashlib计算文件的(md5)哈希值

超大文件如何计算md5?

EXCEL VBA计算带汉字的字符串的MD5值(VBA转UTF-8保存)

javascript 计算文件MD5 浏览器 javascript读取文件内容

加密算法之 MD5算法