Link to home
Start Free TrialLog in
Avatar of Bajsen
Bajsen

asked on

Hash a file and append the filename to the hash in VB.NET

Hi experts!

I want to hash a file with MD5 and compare it to another file's MD5 hash. According to the SDK this is how it's done in PHP:
/*function getGiantsModMD5Hash($modFile)
{
  $info = pathinfo($modFile);
  // Add mod zip data
  $fileContent = file_get_contents($modFile);
  // Add basefile name string without extension
  $fileContent .= basename($modFile, '.' . $info['extension']);
  return md5($fileContent);
}

That returns a correct hash, but now i want to do this in VB.NET and this is the code that i found do hash a file:
Public Class FileChecksum
    Private Const BUF_SIZE As Integer = 65536
    ''' <summary>
    ''' Returns the file integrity checksum hash, otherwise an empty string.
    ''' </summary>
    Public Shared Function IntegrityCheck(ByVal filePath As String) As String
        Dim dataBuffer(BUF_SIZE - 1) As Byte
        Dim dataBufferDummy(BUF_SIZE - 1) As Byte
        Dim dataBytesRead As Integer = 0
        Dim hashResult As String = String.Empty
        Dim hashAlg As HashAlgorithm = Nothing
        Dim fs As FileStream = Nothing

        Try
            hashAlg = New MD5CryptoServiceProvider ' or New SHA1CryptoServiceProvider
            fs = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None, BUF_SIZE)
            Do
                dataBytesRead = fs.Read(dataBuffer, 0, BUF_SIZE)
                hashAlg.TransformBlock(dataBuffer, 0, dataBytesRead, dataBufferDummy, 0)
            Loop Until dataBytesRead = 0
            hashAlg.TransformFinalBlock(dataBuffer, 0, 0)
            hashResult = BitConverter.ToString(hashAlg.Hash).Replace("-", "").ToLower
        Catch ex As IOException
            MsgBox(ex.Message, MsgBoxStyle.Critical, "IntegrityCheck")
        Catch ex As UnauthorizedAccessException
            MsgBox(ex.Message, MsgBoxStyle.Critical, "IntegrityCheck")
        Finally
            If Not fs Is Nothing Then
                fs.Close()
                fs.Dispose()
                fs = Nothing
            End If
            If Not hashAlg Is Nothing Then
                hashAlg.Clear() 'Dispose()
                hashAlg = Nothing
            End If
        End Try
        Return hashResult
    End Function

However, as you can the in the PHP example, i must also append the filename whiteout the extension to the end before i calculate the MD5 hash. How in the world do i do that? I've been trying to solve this for the last two days now. :/
Avatar of David Johnson, CD
David Johnson, CD
Flag of Canada image

Microsoft .net has done most of the heavy lifting for you.
System.Security.Cryptography supports many hash algorithms
MD5, RIPEMD160, SHA1, SHA256, SHA384, SHA512

you basically open a file stream, set the pointer to 0 (beginning of file)
have the hasher read the file and return the value.


http://us.informatiweb.net/programmation/36--generate-hashes-md5-sha-1-and-sha-256-of-a-file.html
https://msdn.microsoft.com/en-us/library/xa627k19%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports System.Windows.Forms

Public Class HashDirectory

    Public Shared Sub Main(ByVal args() As String)
        Dim directory As String 
        If args.Length < 1 Then 
            Dim fdb As New FolderBrowserDialog
            Dim dr As DialogResult = fdb.ShowDialog()
            If (dr = DialogResult.OK) Then
                directory = fdb.SelectedPath
            Else
                Console.WriteLine("No directory selected")
                Return 
            End If 
        Else
            directory = args(0)
        End If 
        Try 
            ' Create a DirectoryInfo object representing the specified directory. 
            Dim dir As New DirectoryInfo(directory)
            ' Get the FileInfo objects for every file in the directory. 
            Dim files As FileInfo() = dir.GetFiles()
            ' Initialize a RIPE160 hash object. 
            Dim myRIPEMD160 As RIPEMD160 = RIPEMD160Managed.Create()
            Dim hashValue() As Byte 
            ' Compute and print the hash values for each file in directory. 
            Dim fInfo As FileInfo
            For Each fInfo In files
                ' Create a fileStream for the file. 
                Dim fileStream As FileStream = fInfo.Open(FileMode.Open)
                ' Be sure it's positioned to the beginning of the stream.
                fileStream.Position = 0
                ' Compute the hash of the fileStream.
                hashValue = myRIPEMD160.ComputeHash(fileStream)
                ' Write the name of the file to the Console.
                Console.Write(fInfo.Name + ": ")
                ' Write the hash value to the Console.
                PrintByteArray(hashValue)
                ' Close the file.
                fileStream.Close()
            Next fInfo
            Return 
        Catch DExc As DirectoryNotFoundException
            Console.WriteLine("Error: The directory specified could not be found.")
        Catch IOExc As IOException
            Console.WriteLine("Error: A file in the directory could not be accessed.")
        End Try 

    End Sub 

    ' Print the byte array in a readable format. 
    Public Shared Sub PrintByteArray(ByVal array() As Byte)
        Dim i As Integer 
        For i = 0 To array.Length - 1
            Console.Write(String.Format("{0:X2}", array(i)))
            If i Mod 4 = 3 Then
                Console.Write(" ")
            End If 
        Next i
        Console.WriteLine()

    End Sub 'PrintByteArray
End Class

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Robberbaron (robr)
Robberbaron (robr)
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial