Vb.net 生成MD5和SHA1

Vb.net 生成MD5和SHA1,vb.net,Vb.net,我正在使用下面的函数为SQL备份文件生成MD5\SH1哈希。 这工作得很好,有进度报告等,但如果使用大文件,速度会很慢 我是否可以在生成SH1的同时生成MD5,而不必两次处理该文件,从而使所用时间加倍?如何将MD5结果转换为SHA1 Imports System Imports System.IO Imports System.Security.Cryptography Imports System.Text Public Class ASyncFileHashAlgorithm Prote

我正在使用下面的函数为SQL备份文件生成MD5\SH1哈希。 这工作得很好,有进度报告等,但如果使用大文件,速度会很慢

我是否可以在生成SH1的同时生成MD5,而不必两次处理该文件,从而使所用时间加倍?如何将MD5结果转换为SHA1

Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text


Public Class ASyncFileHashAlgorithm
Protected hashAlgorithm As HashAlgorithm
Protected m_hash As Byte()
Protected cancel As Boolean = False
Protected m_bufferSize As Integer = 4096
Public Delegate Sub FileHashingProgressHandler(ByVal sender As Object, _
                                     ByVal e As FileHashingProgressArgs)
Public Event FileHashingProgress As FileHashingProgressHandler

Public Sub New(ByVal hashAlgorithm As HashAlgorithm)
    Me.hashAlgorithm = hashAlgorithm
End Sub

Public Function ComputeHash(ByVal stream As Stream) As Byte()
    cancel = False
    m_hash = Nothing
    Dim _bufferSize As Integer = m_bufferSize
    ' this makes it impossible to change the buffer size while computing  
    Dim readAheadBuffer As Byte(), buffer As Byte()
    Dim readAheadBytesRead As Integer, bytesRead As Integer
    Dim size As Long, totalBytesRead As Long = 0

    size = stream.Length
    readAheadBuffer = New Byte(_bufferSize - 1) {}
    readAheadBytesRead = stream.Read(readAheadBuffer, 0, _
                                     readAheadBuffer.Length)

    totalBytesRead += readAheadBytesRead

    Do
        bytesRead = readAheadBytesRead
        buffer = readAheadBuffer

        readAheadBuffer = New Byte(_bufferSize - 1) {}
        readAheadBytesRead = stream.Read(readAheadBuffer, 0, _
                                         readAheadBuffer.Length)

        totalBytesRead += readAheadBytesRead

        If readAheadBytesRead = 0 Then
            hashAlgorithm.TransformFinalBlock(buffer, 0, bytesRead)
        Else
            hashAlgorithm.TransformBlock(buffer, 0, bytesRead, buffer, 0)
        End If

        RaiseEvent FileHashingProgress(Me, New _
                             FileHashingProgressArgs(totalBytesRead, size))
    Loop While readAheadBytesRead <> 0 AndAlso Not cancel

    If cancel Then
        Return InlineAssignHelper(m_hash, Nothing)
    End If

    Return InlineAssignHelper(m_hash, hashAlgorithm.Hash)
End Function

Public Property BufferSize() As Integer
    Get
        Return m_bufferSize
    End Get
    Set(ByVal value As Integer)
        m_bufferSize = value
    End Set
End Property

Public ReadOnly Property Hash() As Byte()
    Get
        Return m_hash
    End Get
End Property

'Public Sub Cancel()
'    cancel = True
'End Sub

Public Overrides Function ToString() As String
    Dim hex As String = ""
    For Each b As Byte In Hash
        hex += b.ToString("x2")
    Next

    Return hex
End Function
Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, _
                                                 ByVal value As T) As T
    target = value
    Return value
End Function
End Class


Public Class FileHashingProgressArgs
Inherits EventArgs
Public Property TotalBytesRead() As Long
    Get
        Return m_TotalBytesRead
    End Get
    Set(ByVal value As Long)
        m_TotalBytesRead = Value
    End Set
End Property
Private m_TotalBytesRead As Long
Public Property Size() As Long
    Get
        Return m_Size
    End Get
    Set(ByVal value As Long)
        m_Size = Value
    End Set
End Property
Private m_Size As Long

Public Sub New(ByVal totalBytesRead__1 As Long, ByVal size__2 As Long)
    TotalBytesRead = totalBytesRead__1
    Size = size__2
End Sub
End Class

您的
ToString
方法可能会为大型字符串创建巨大的开销,因为串联非常昂贵(它会创建大型临时缓冲区),而且您经常这样做。改用
StringBuilder
(用正确的大小初始化)。

出于好奇,为什么要同时使用这两个哈希函数?这还不够吗?您不能将MD5转换为SHA,反之亦然。这两个值都会生成并传递给使用MD5或SHA验证备份的客户端。在理想的世界里,他们都会使用一种方法!
Shared hasher As New ASyncFileHashAlgorithm(SHA1.Create())

Private Function Test(Byval (strFilePathAndName, as String)


Dim stream As IO.Stream = DirectCast(File.Open(strFilePathAndName, _
                                               FileMode.Open), Stream)

        AddHandler hasher.FileHashingProgress, _
                   AddressOf OnFileHashingProgress

        Dim t = New Thread(AddressOf hasher.ComputeHash)
        t.Start(stream)
        While t.IsAlive
            Application.DoEvents()
        End While


        'LblMD5.Text = hasher.ToString???
        LblSHA1.Text = hasher.ToString

        stream.Dispose()

End Sub

Public Sub OnFileHashingProgress(ByVal sender As Object, _
                                 ByVal e As FileHashingProgressArgs)

    SetControlPropertyValue(uxChildForm.ProgressBar, "Position", _
                            CInt(e.TotalBytesRead / e.Size * 100))

End Sub