2020年5月21日 星期四

VB.NET Using Hashes To Check If A File Changed


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
Public Class frmCheckFile

  Private fileToCheck As String = ""

  Private fileHash As Byte()


  ' Select file button opens a file dialog to select a file to check.

  Private Sub btnSelectFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectFile.Click

    If dlgOpenFile.ShowDialog() = DialogResult.OK Then

      If Not String.IsNullOrEmpty(dlgOpenFile.FileName) Then


        ' Save the file name so we can check later.

        ' Then compute its hash and save that.

        fileToCheck = dlgOpenFile.FileName

        fileHash = ComputeFileHash(fileToCheck)

      Else

        MessageBox.Show("Please select a valid file to compute the hash for.")

      End If

    End If


  End Sub



  ' Check File button recomputes hash for the saved file name and compares it to the old saved hash.

  Private Sub btnCheckFileChanges_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCheckFileChanges.Click

    If Not String.IsNullOrEmpty(fileToCheck) Then

      Dim newFileHash As Byte() = ComputeFileHash(fileToCheck)


      If CompareByteHashes(newFileHash, fileHash) Then

        MessageBox.Show("They are the same, no changes were made.")

      Else

        MessageBox.Show("The file " + fileToCheck + " was changed.")


      End If

    Else

      MessageBox.Show("Please select a file to hash before you attempt to check it for changes.")

    End If

  End Sub



  ' Simply opens up the file name we have stored and appends a byte onto the end of it to change it slightly.

  Private Sub btnChangeSlightly_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnChangeSlightly.Click

    If Not String.IsNullOrEmpty(fileToCheck) Then

      Try

        Dim fileToChange As FileStream = New FileStream(fileToCheck, FileMode.Open, FileAccess.Write)


        ' Write a byte representing "A" onto the end of the file.

        fileToChange.Seek(fileToHash.Length, SeekOrigin.Begin)

        fileToChange.WriteByte(65)

        fileToChange.Close()


        MessageBox.Show("File successfully modified.")


      Catch ex As IOException

        MessageBox.Show("Error opening or writing to file: " & ex.Message)

      End Try


    Else

      MessageBox.Show("Please select a file to check/change first before trying to change it.")

    End If

  End Sub



  ' Calculates a file's hash value and returns it as a byte array.

  Private Function ComputeFileHash(ByVal fileName As String) As Byte()

    Dim ourHash(0) As Byte


    ' If file exists, create a HashAlgorithm instance based off of MD5 encryption

    ' You could use a variant of SHA or RIPEMD160 if you like with larger hash bit sizes.

    If File.Exists(fileName) Then

      Try

        Dim ourHashAlg As HashAlgorithm = HashAlgorithm.Create("MD5")

        Dim fileToHash As FileStream = New FileStream(fileName, FileMode.Open, FileAccess.Read)


        'Compute the hash to return using the Stream we created.

        ourHash = ourHashAlg.ComputeHash(fileToHash)


        fileToHash.Close()

      Catch ex As IOException

        MessageBox.Show("There was an error opening the file: " & ex.Message)

      End Try

    End If


    Return ourHash

  End Function



  ' Return true/false if the two hashes are the same.

  Private Function CompareByteHashes(ByVal newHash As Byte(), ByVal oldHash As Byte()) As Boolean


    ' If any of these conditions are true, the hashes are definitely not the same.

    If newHash Is Nothing Or oldHash Is Nothing Or newHash.Length <> oldHash.Length Then

      Return False

    End If



    ' Compare each byte of the two hashes. Any time they are not the same, we know there was a change.

    For i As Integer = 0 To newHash.Length - 1

      If newHash(i) <> oldHash(i) Then

        Return False

      End If

    Next i


    Return True

  End Function

End Class

沒有留言:

張貼留言