CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    MD5 Hashing not quite working out ...

    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....
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  2. #2
    Join Date
    Aug 2005
    Location
    Imperial College London, England
    Posts
    490

    Re: MD5 Hashing not quite working out ...

    If you think It would be of help, I could post the VB6 MD5 code for you to compare against. But I can't see that being of much use.
    Help from me is always guaranteed!*
    VB.NET code is made up on the spot with VS2008 Professional with .NET 3.5. Everything else is just made up on the spot.
    Please Remember to rate posts, use code tags, send me money and all the other things listed in the "Before you post" posts.

    *Guarantee may not be honoured.

  3. #3
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    Re: MD5 Hashing not quite working out ...

    If you've got VB6 MD5 Hashing code .. Please, I'd like to use it to compare...

    Thanks..
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  4. #4
    Join Date
    Aug 2005
    Location
    Imperial College London, England
    Posts
    490

    Re: MD5 Hashing not quite working out ...

    Here we go...
    Enjoy!
    Attached Files Attached Files
    Help from me is always guaranteed!*
    VB.NET code is made up on the spot with VS2008 Professional with .NET 3.5. Everything else is just made up on the spot.
    Please Remember to rate posts, use code tags, send me money and all the other things listed in the "Before you post" posts.

    *Guarantee may not be honoured.

  5. #5
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    Re: MD5 Hashing not quite working out ...

    Okay i found where i'm going wrong .. ..

    I forgot about Little endian and big endian .. I'm working almost everything in big ...

    Ouch ...

    Time to sort it all out...

    Gremmy
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

  6. #6
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    Re: MD5 Hashing not quite working out ...

    Ya hoo ... I got it sorted ..

    Thank javajawa, that module did help, i now get the correct MD5 Hash for the test strings...

    Now to finilise the complete MD5 Class....

    Gremmy....
    Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
    WPF Articles : 3D Animation 1 , 2 , 3
    Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
    Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
    All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured