Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1514

[VB6/VBA] Pure VB6 implementation of MD5 hash for the grins :-))

$
0
0
md5.bas is a 120 lines of code implementation of MD5 message digest as specified in RFC 1321.

Code:

'--- md5.bas
Option Explicit
DefObj A-Z

#Const HasPtrSafe = (VBA7 <> 0) Or (TWINBASIC <> 0)

#If HasPtrSafe Then
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
#Else
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
#End If

Private LNG_POW2(0 To 31)  As Long
Private S(0 To 15)          As Long
Private K(0 To 63)          As Long

Private Function ROTL32(ByVal lX As Long, ByVal lN As Long) As Long
    '--- ROTL32 = LShift(X, n) Or RShift(X, 32 - n)
    Debug.Assert lN <> 0
    ROTL32 = ((lX And (LNG_POW2(31 - lN) - 1)) * LNG_POW2(lN) Or -((lX And LNG_POW2(31 - lN)) <> 0) * LNG_POW2(31)) Or _
        ((lX And (LNG_POW2(31) Xor -1)) \ LNG_POW2(32 - lN) Or -(lX < 0) * LNG_POW2(lN - 1))
End Function

Private Function UAdd(ByVal lX As Long, ByVal lY As Long) As Long
    If (lX Xor lY) > 0 Then
        UAdd = ((lX Xor &H80000000) + lY) Xor &H80000000
    Else
        UAdd = lX + lY
    End If
End Function

Public Sub CryptoMd5(baOutput() As Byte, baInput() As Byte, Optional ByVal Pos As Long, Optional ByVal Size As Long = -1)
    Dim vElem          As Variant
    Dim lIdx            As Long
    Dim lA              As Long
    Dim lB              As Long
    Dim lC              As Long
    Dim lD              As Long
    Dim lA2            As Long
    Dim lB2            As Long
    Dim lC2            As Long
    Dim lD2            As Long
    Dim lR              As Long
    Dim lE              As Long
    Dim lTemp          As Long
    Dim aBuffer()      As Long
    Dim lBufPos        As Long
    Dim lBufIdx        As Long
   
    If LNG_POW2(0) = 0 Then
        LNG_POW2(0) = 1
        For lIdx = 1 To 30
            LNG_POW2(lIdx) = LNG_POW2(lIdx - 1) * 2
        Next
        LNG_POW2(31) = &H80000000
        lIdx = 0
        For Each vElem In Split("7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21")
            S(lIdx) = vElem
            lIdx = lIdx + 1
        Next
        For lIdx = 0 To 63
            vElem = Abs(Sin(lIdx + 1)) * 4294967296#
            K(lIdx) = Int(IIf(vElem > 2147483648#, vElem - 4294967296#, vElem))
        Next
    End If
    If Size < 0 Then
        Size = UBound(baInput) + 1 - Pos
    End If
    '--- pad input buffer to 64 bytes
    lIdx = 64 - (Size Mod 64)
    If lIdx < 9 Then
        lIdx = lIdx + 64
    End If
    ReDim aBuffer(0 To (Size + lIdx) \ 4 - 1) As Long
    If Size > 0 Then
        Call CopyMemory(aBuffer(0), baInput(Pos), Size)
    End If
    Call CopyMemory(ByVal VarPtr(aBuffer(0)) + Size, &H80, 1)
    aBuffer(UBound(aBuffer) - 1) = Size * 8
    '--- md5 step
    lA = &H67452301: lB = &HEFCDAB89: lC = &H98BADCFE: lD = &H10325476
    Do While lBufPos < UBound(aBuffer)
        lA2 = lA: lB2 = lB: lC2 = lC: lD2 = lD
        For lIdx = 0 To 63
            lR = lIdx \ 16
            Select Case lR
            Case 0
                lE = (lB2 And lC2) Or (Not lB2 And lD2)
                lBufIdx = lIdx
            Case 1
                lE = (lB2 And lD2) Or (lC2 And Not lD2)
                lBufIdx = (lIdx * 5 + 1) And 15
            Case 2
                lE = lB2 Xor lC2 Xor lD2
                lBufIdx = (lIdx * 3 + 5) And 15
            Case 3
                lE = lC2 Xor (lB2 Or Not lD2)
                lBufIdx = (lIdx * 7) And 15
            End Select
            lTemp = lD2
            lD2 = lC2
            lC2 = lB2
            lB2 = UAdd(lB2, ROTL32(UAdd(UAdd(UAdd(lA2, lE), K(lIdx)), aBuffer(lBufPos + lBufIdx)), S((lR * 4) Or (lIdx And 3))))
            lA2 = lTemp
        Next
        lA = UAdd(lA, lA2): lB = UAdd(lB, lB2): lC = UAdd(lC, lC2): lD = UAdd(lD, lD2)
        lBufPos = lBufPos + 16
    Loop
    '--- complete output
    aBuffer(0) = lA: aBuffer(1) = lB: aBuffer(2) = lC: aBuffer(3) = lD
    ReDim baOutput(0 To 15) As Byte
    Call CopyMemory(baOutput(0), aBuffer(0), 16)
End Sub

cheers,
</wqw>

Viewing all articles
Browse latest Browse all 1514

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>