はじめに
ファイルの同一性を確認する際に、求めたハッシュ値をExcelのシート上に貼り付けて保存しようと考えたのですが、Excelの関数にはハッシュ値を求める処理がありません。
そこで、「CertUtilコマンドでハッシュ値を求めた後、その結果をExcel(VBA)側で受け取る」という処理を作ってみました。
作成した関数
- 第一引数にハッシュ値を求めたいファイルのパス、第二引数にハッシュアルゴリズムを指定することで、所望のハッシュ値を取得することができます。
- MS-DOSのコマンドを実行して、その結果を取得する方法については以下の記事を参考にしました。
- MS-DOSコマンドの標準出力を取得する
- CertUtilコマンドの結果には、以下のように不要な行も出力されてしまうので、
findstr
コマンドを使って「特定のパターンにマッチする不要な行」を除去しています。 MD5 ハッシュ (対象 sample.txt):
CertUtil: -hashfile コマンドは正常に完了しました。
- findstrコマンドの使い方については、こちらのページに詳しく書かれています。
DigestUtils.bas
'--------------------------------------------------------------------------------
' 引数で指定したファイルのハッシュ値(ダイジェスト値)を取得する。
'
' filePath:ファイルパス。
' hashAlgorithm:ハッシュアルゴリズムの種類。MD5,SHA1,SHA256などを指定可能。
' return:ファイルのハッシュ値(ダイジェスト値)
'--------------------------------------------------------------------------------
Public Function HashFile(filePath As String, hashAlgorithm As String) As String
Dim wsh As Object, wExec As Object, command As String, output As String
Set wsh = CreateObject("WScript.Shell")
command = "certutil -hashfile " & filePath & " " & hashAlgorithm & " | findstr /V CertUtil | findstr /V " & hashAlgorithm
Set wExec = wsh.Exec("%ComSpec% /c " & command)
Do While wExec.Status = 0
DoEvents
Loop
output = wExec.stdOut.ReadAll
Set wExec = Nothing
Set wsh = Nothing
HashFile = output
End Function
テストコード
Public Sub TestHashFile()
Debug.Print HashFile("C:\test\hoge.ps1", "MD5")
End Sub
実行結果
b855794c5edc59be568aa34a8b0f9ff1
余談
- CertUtilコマンドについては、Windowsのバージョンによって異なる結果になるため、得られたハッシュ値の取り扱いには注意が必要です。
- 第二引数のハッシュアルゴリズムの選択にはEnumを使いたかったのですが、Enumのシンボル文字列が取得できないので断念しました。
- VBAの組み込み関数を補うために作成した自作の関数は、以下のページにもアップしています。
- 【ExcelVBA】文字列操作用のユーティリティ関数を自作してみた
- 【ExcelVBA】日時操作用のユーティリティ関数を自作してみた