theskiguy Ответов: 1

Ложноположительный результат от алгоритма хеширования, используемого для проверки равенства файлов


У меня есть код, который я изначально нашел в кулинарной книге VB, который проверяет 2 файла на равенство. Решение генерирует контрольную сумму для каждого файла, а затем сравнивает контрольные суммы. В моем исходном приложении все работало нормально, поэтому недавно я решил использовать ту же логику в другом приложении. Причина, по которой я хочу использовать этот код, заключается в том, что я хочу проверить, соответствует ли текстовый файл, который я только что скопировал с сетевого сервера, файлу в сети. Во время тестирования своего нового приложения я заметил, что получаю случайные ложные срабатывания. (Приложение сообщает, что файлы не равны, но программа сравнения текстов сообщает, что они равны). Если я закрою и перезапущу приложение, а затем сразу же скопирую и снова сравню файлы, тогда оно скажет, что они равны. Если мы не закроем приложение и просто попробуем его снова, оно все равно скажет, что они неравны. Я даже тестировал приложение на другом аналогичном компьютере, и на нем тоже возникают случайные проблемы.

Я пытаюсь понять, почему это происходит? Если файл используется другим процессом, вызовет ли это проблему? Может быть, это связано с аппаратным обеспечением? Эти машины все еще работают под управлением Win 2000 и имеют ограниченную оперативную память. Просто пытаюсь понять, что может быть не так, чтобы попробовать что-то другое.

Что я уже пробовал:

Public Function CopyAndCheckIfFilesAreIdentical(ByVal SourceFileName As String, ByVal DestFileName As String, ByVal OverwriteFile As Boolean) As Integer


        'This function copies a file and then compares the copied file using a hashing algorithm
        'Result = 1 = Files are identical
        'Result = 0 = Files are different
        'Result = -1 = File(s) don't exist

        Dim Result As Integer = 0
        Dim TheFilesAreIdentical As Boolean


        'Copy the file first
        System.IO.File.Copy(SourceFileName, DestFileName, OverwriteFile)

        'Make sure the files exist
        If System.IO.File.Exists(SourceFileName) = True And System.IO.File.Exists(DestFileName) = True Then
            TheFilesAreIdentical = AreFilesIdentical(SourceFileName, DestFileName)
            If TheFilesAreIdentical = True Then
                Result = 1
            Else
                Result = 0
                MsgBox("Source File:  " & SourceFileName & vbNewLine & _
                        "Is NOT identical to" & vbNewLine & _
                        "Dest File:  " & DestFileName, MsgBoxStyle.Critical, "Files not Identical")

            End If

        Else
            Result = -1
            If System.IO.File.Exists(SourceFileName) = False Then
                MsgBox("Source File:  " & SourceFileName & vbNewLine & _
                        "Does not exist" & vbNewLine & _
                        "During Function:  CopyandCheckIfFilesAreIdentical")
            Else
                MsgBox("Dest File:  " & DestFileName & vbNewLine & _
                        "Does not exist" & vbNewLine & _
                        "During Function:  CopyandCheckIfFilesAreIdentical")

            End If

        End If

        Return Result


    End Function


    Public Function AreFilesIdentical(ByVal File1 As String, ByVal File2 As String) As Boolean


        'Return True if the files are identical

        Dim CheckSum1 As Byte()
        Dim CheckSum2 As Byte()
        Dim CheckSum1asString As String
        Dim CheckSum2asString As String
        Dim Counter As Integer


        On Error GoTo ErrorHandler

        'Calculate the CheckSums
        CheckSum1 = GenerateFileCheckSum(File1)
        CheckSum2 = GenerateFileCheckSum(File2)

        CheckSum1asString = BitConverter.ToString(CheckSum1)
        CheckSum2asString = BitConverter.ToString(CheckSum2)

        'See if the results are equal
        For Counter = 0 To UBound(CheckSum1)
            If CheckSum1(Counter) <> CheckSum2(Counter) Then
                Return False
            End If
        Next

        'The CheckSums are True
        Return True


ErrorHandler:

        Return False

    End Function



    Public Function GenerateFileCheckSum(ByVal Filepath As String) As Byte()

        'This function generates a checksum of the file

        Dim HashingFunction As HMACSHA1
        Dim HashingBase() As Byte
        Dim HashValue() As Byte
        Dim InStream As IO.Stream


        'Make sure the file exists
        If My.Computer.FileSystem.FileExists(Filepath) = False Then
            Throw New IO.FileNotFoundException
            Return Nothing
        End If

        'Prepare the hashing key.  You have to use the same hashing key everytime to get the same results
        HashingBase = (New UnicodeEncoding).GetBytes("Cookbook")

        'Create the hashing component using the Managed SHA-1 function
        HashingFunction = New HMACSHA1(HashingBase, True)

        'Open the file as a stream
        InStream = New IO.FileStream(Filepath, IO.FileMode.Open, IO.FileAccess.Read)

        'Calculate the checksum value
        HashValue = HashingFunction.ComputeHash(InStream)

        'Finished with the file
        InStream.Close()

        'Return the checksum as a byte array
        Return HashValue


    End Function

1 Ответов

Рейтинг:
6

OriginalGriff

Цитата:
Если файл используется другим процессом, вызовет ли это проблему?
Что ж... настоящий кодекс:
        On Error GoTo ErrorHandler
...
ErrorHandler:
        Return False
Это означало бы, что если бы файл был использован, он вернул бы false - так что все, что означает, что он не может выполнить задачу, дало бы вам "случайный" сигнал "нет совпадения".

Но, пожалуйста, полностью забудьте "по ошибке ..." и используйте Try ... Блок catch. Они дадут вам гораздо лучшую информацию о том, что произошло, чтобы вызвать проблему как часть объекта исключения, и это будет означать, что отслеживание именно того, почему это проблема, должно быть намного проще.

Поскольку он прерывистый, я бы, вероятно, начал с проверки одного и того же файла на равенство: если это когда-нибудь не удастся, то проблема не в самом файле...