I have a requirement to MD5Hash certain parts of a file .. (so i need some control over what gets hashed)..

So i looked up the specs ...
Quote Originally Posted by Wiki
Pseudo Code
'//Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating
'var int[64] r, k

'//r specifies the per-round shift amounts
'r[ 0..15] := {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22}
'r[16..31] := {5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20}
'r[32..47] := {4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23}
'r[48..63] := {6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}

'//Use binary integer part of the sines of integers (Radians) as constants:
'for i from 0 to 63
' k[i] := floor(abs(sin(i + 1)) × (2 pow 32))

'//Initialize variables:
'var int h0 := 0x01234567
'var int h1 := 0x89ABCDEF
'var int h2 := 0xFEDCBA98
'var int h3 := 0x76543210

'//Pre-processing:
'append "1" bit to message
'append "0" bits until message length in bits ≡ 448 (mod 512)
' 56 (mod 64)
'append bit /* bit, not byte */ length of unpadded message as 64-bit little-endian integer to message

'//Process the message in successive 512-bit chunks:
'for each 512-bit chunk of message
' break chunk into sixteen 32-bit little-endian words w[i], 0 ≤ i ≤ 15

' //Initialize hash value for this chunk:
' var int a := h0
' var int b := h1
' var int c := h2
' var int d := h3

' //Main loop:
' for i from 0 to 63
' if 0 ≤ i ≤ 15 then
' f := (b and c) or ((not b) and d)
' g := i
' else if 16 ≤ i ≤ 31
' f := (d and b) or ((not d) and c)
' g := (5×i + 1) mod 16
' else if 32 ≤ i ≤ 47
' f := b xor c xor d
' g := (3×i + 5) mod 16
' else if 48 ≤ i ≤ 63
' f := c xor (b or (not d))
' g := (7×i) mod 16

' temp := d
' d := c
' c := b
' b := b + leftrotate((a + f + k[i] + w[g]) , r[i])
' a := temp

' //Add this chunk's hash to result so far:
' h0 := h0 + a
' h1 := h1 + b
' h2 := h2 + c
' h3 := h3 + d

'var int digest := h0 append h1 append h2 append h3 //(expressed as little-endian)

' //leftrotate function definition
' leftrotate (x, c)
' return (x << c) or (x >> (32-c));
I've pretty much got most of the core of this working.. However when running a few test strings i'm getting the wrong hash back ..

running MD5 on ("") should give "d41d8cd98f00b204e9800998ecf8427e" however i'm getting "E0BA2C792CFD07E92768A891C861AB11"

I've previously done a CRC 16 Module from simular pseudo code, that worked 100%, but i'm batteling with this one for several days now..

Code:
Public Class MD5Hash
    Private R() As UInt32
    Private K() As UInt32
    Private H() As UInt32
    Private Pre() As UInt32
    Private A() As UInt32
    Private _Size As Integer
    Private _Current As Integer

    Public Sub New()
        InitK()
        InitR()
    End Sub

    Public Sub Reset(ByVal FinSize As Integer)
        ReDim H(3)
        ReDim Pre(3)
        ReDim A(3)
        'ReDim Block(15)
        _Size = FinSize
        _Current = 0

        H(0) = &H1234567&
        H(1) = &H89ABCDEF&
        H(2) = &HFEDCBA98&
        H(3) = &H76543210&

    End Sub

    Private Sub InitR()
        Dim S() As String
        Dim TmpInt As Integer
        ReDim R(63)

        S = Split("7,12,17,22, 7,12,17,22, 7,12,17,22, 7,12,17,22," & _
                  "5,9,14,20, 5,9,14,20, 5,9,14,20, 5,9,14,20," & _
                  "4,11,16,23, 4,11,16,23, 4,11,16,23, 4,11,16,23," & _
                  "6,10,15,21, 6,10,15,21, 6,10,15,21, 6,10,15,21 ", ",")

        For TmpInt = 0 To 63
            R(TmpInt) = Val(S(TmpInt))
        Next
    End Sub

    Private Sub InitK()
        Dim TmpInt As Integer
        Dim S() As String
        S = Split("D76AA478,E8C7B756,242070DB,C1BDCEEE,F57C0FAF,4787C62A,A8304613,FD469501," & _
                  "698098D8,8B44F7AF,FFFF5BB1,895CD7BE,6B901122,FD987193,A679438E,49B40821," & _
                  "F61E2562,C040B340,265E5A51,E9B6C7AA,D62F105D,02441453,D8A1E681,E7D3FBC8," & _
                  "21E1CDE6,C33707D6,F4D50D87,455A14ED,A9E3E905,FCEFA3F8,676F02D9,8D2A4C8A," & _
                  "FFFA3942,8771F681,6D9D6122,FDE5380C,A4BEEA44,4BDECFA9,F6BB4B60,BEBFBC70," & _
                  "289B7EC6,EAA127FA,D4EF3085,04881D05,D9D4D039,E6DB99E5,1FA27CF8,C4AC5665," & _ 
                  "F4292244,432AFF97,AB9423A7,FC93A039,655B59C3,8F0CCC92,FFEFF47D,85845DD1," & _ 
                  "6FA87E4F,FE2CE6E0,A3014314,4E0811A1,F7537E82,BD3AF235,2AD7D2BB,EB86D391", ",")

        ReDim K(63)
        For TmpInt = 0 To 63
            K(TmpInt) = CUint32(S(TmpInt))
        Next
    End Sub

    Private Function LeftRotate(ByVal InVal As UInt32, ByVal Bits As Integer) As UInt32
        Dim TmpInt As Integer
        For TmpInt = 1 To Bits
            If InVal And &H80000000& Then
                InVal = (InVal << 1) Or &H1
            Else
                InVal = (InVal << 1)
            End If
        Next
        Return InVal
    End Function

    Private Function F1(ByVal X As UInt32, ByVal Y As UInt32, ByVal Z As UInt32) As UInt32
        Return (X And Y) Or (Not (X) And Z)
    End Function

    Private Function F2(ByVal X As UInt32, ByVal Y As UInt32, ByVal Z As UInt32) As UInt32
        Return (X And Z) Or (Not (Y) And Z)
    End Function

    Private Function F3(ByVal X As UInt32, ByVal Y As UInt32, ByVal Z As UInt32) As UInt32
        Return X Xor Y Xor Z
    End Function

    Private Function F4(ByVal X As UInt32, ByVal Y As UInt32, ByVal Z As UInt32) As UInt32
        Return Y Xor (X Or (Not Z))
    End Function

    Private Function Hex8(ByVal Value As UInt32) As String
        Dim s As String

        s = Hex(Value)
        Do While (Len(s) < 8)
            s = "0" & s
        Loop
        Return s
    End Function

    Private Function Hex16(ByVal Value As UInt64) As String
        Dim s As String

        s = Hex(Value)
        Do While (Len(s) < 16)
            s = "0" & s
        Loop
        Return s

    End Function

    Private Function CUint32(ByVal Hex As String) As UInt32
        Dim tmpInt As Integer

        CUint32 = 0
        For tmpInt = 0 To Hex.Length - 1
            CUint32 = (CUint32 * &H10) + Val("&H" & Hex.Substring(tmpInt, 1))
        Next
    End Function

    Public ReadOnly Property GetHash() As String
        Get
            Return Hex8(H(0)) & Hex8(H(1)) & Hex8(H(2)) & Hex8(H(3))
        End Get
    End Property

    Private Sub Core(ByVal Block() As UInt32)
        Dim Tmpint As Integer
        Dim TmpUint As UInt32
        Dim F As UInt32
        Dim G As UInt32
        Dim Tmp1Int64 As Int64
        Dim Tmp2Int64 As Int64


        If Block.Length <> 16 Then
            MsgBox("MD5 Data Object Incorect Size")
            Exit Sub
        End If
        For Tmpint = 0 To 63
            Select Case Tmpint
                Case 0 To 15
                    F = F1(A(1), A(2), A(3))
                    G = Tmpint
                Case 16 To 31
                    F = F2(A(1), A(2), A(3))
                    G = (5 * Tmpint + 1) Mod 16
                Case 32 To 47
                    F = F3(A(1), A(2), A(3))
                    G = (3 * Tmpint + 5) Mod 16
                Case 48 To 63
                    F = F4(A(1), A(2), A(3))
                    G = (7 * Tmpint) Mod 16

            End Select
            TmpUint = A(3)
            A(3) = A(2)
            A(2) = A(1)
            Tmp1Int64 = F
            Tmp1Int64 += A(0)
            Tmp1Int64 += K(Tmpint)
            Tmp1Int64 += Block(G)
            Tmp1Int64 = Tmp1Int64 And &HFFFFFFFF&
            Tmp2Int64 = A(1)
            Tmp2Int64 += LeftRotate(CUInt(Tmp1Int64), R(Tmpint))
            A(1) = Tmp2Int64 And &HFFFFFFFF&
            A(0) = TmpUint
        Next
    End Sub

    Public Sub MD5(ByVal Data() As UInt32)
        Dim TmpInt64 As Int64
        Dim TmpInt As Integer
        If Data.Length <> 16 Then
            MsgBox("MD5 Data Object Incorect Size")
            Exit Sub
        End If
        A(0) = H(0)
        A(1) = H(1)
        A(2) = H(2)
        A(3) = H(3)
        Core(Data)
        For TmpInt = 0 To 3
            TmpInt64 = H(TmpInt)
            TmpInt64 += A(TmpInt)
            H(TmpInt) = TmpInt64 And &HFFFFFFFF
        Next

    End Sub

    Public Sub MD5(ByVal Data() As Byte)
        Dim DataInt32() As UInt32
        Dim Tmpint As Integer
        Dim Tmpint2 As Integer
        If Data.Length <> 64 Then
            MsgBox("MD5 Data Object Incorect Size")
            Exit Sub
        End If

        ReDim DataInt32(15)
        For Tmpint = 0 To 15
            For Tmpint2 = 0 To 3
                DataInt32(Tmpint) = (DataInt32(Tmpint) * &H100) + Data(Tmpint * 4 + Tmpint2)
            Next
        Next
        MD5(DataInt32)
    End Sub

End Class
Could someone please check where i'm going wrong here ...

Thanks
Gremmy....