Jump to content

Free MD5 Hash DLL with source


cbruce
 Share

Recommended Posts

When searching here, I saw several requests for an MD5 routine, and since I needed one myself I just ported one over from PowerBASIC to FreeBASIC so that everyone here could use it also.

Here's the AutoIt code to test it with:

;=====================================================
; Test_MD5_Hash_DLL.au3
; Bruce Huber  September 18, 2008
;=====================================================

; CalcMD5("This is a test", MD5_Digest)
; Expected output for that input string = 'ce114e4501d2f4e2dcea3e17b546f339'

; MD5_Digest string is 33 bytes.
; So you should pre-fill that parameter string with at least 35 characters
; to allow for additional null bytes at the end of the DLL's ASCIIZ string.

;==============================================
; INCLUDES
;==============================================

#include <String.au3>

;==============================================
; INIT CODE
;==============================================

Dim $parm1, $parm2, $result, $save_error

;=====================================================
; FUNCTIONS
;=====================================================

Func dp( $dbgTXT)
DllCall( "kernel32.dll", "none", "OutputDebugString", "str", $dbgTXT)
EndFunc

;=====================================================
; MAIN()
;=====================================================

dp( "DBGVIEWCLEAR")

;   ---------------------------------------------------------
;   -----  This is the only part you need to get MD5 hashes
;   -----  The rest is Debug output
$parm1 = "This is a test"
$parm2 = _StringRepeat( " ", 50)

$result = DllCall("MD5_Hash.dll", "none:cdecl", "CalcMD5", "str", $parm1, "str", $parm2)
$save_error = @error
;   ---------------------------------------------------------

dp( "MD5_Hash.dll")
dp( "@error = " & $save_error)
dp( "1 = " & $result[1])
dp( "2 = " & $result[2])
dp( "$parm2 = " & $parm2)
dp( "R = " & $result[0])

; As you can see, $parm2 does NOT contain the returned value.
;
; $result[2] will contain the MD5_Digest string value after the function call.

#cs
------------  Sample output  -------------
MD5_Hash.dll
@error = 0
1 = This is a test
2 = CE114E4501D2F4E2DCEA3E17B546F339
$parm2 =                                                   
R = 
#ce

And here's the FreeBASIC MD5 Hash DLL code:

'=====================================================
' MD5_Hash.dll
' Bruce Huber  September 18, 2008
'=====================================================

' MD5 Message Digest Algorithm.

' FreeBASIC command line to compile the DLL:
' fbc -s gui -dll -export MD5_Hash.bas

' Original PowerBASIC version - Trevor Lane - Aug 27th, 2001, 08:50 AM
' [url="http://www.powerbasic.com/support/pbforums/showthread.php?t=23119"]http://www.powerbasic.com/support/pbforums/showthread.php?t=23119[/url]
'
' Converted from:
' A Javascript implementation of the RSA Data Security, Inc. MD5 Message
' Digest Algorithm, as defined In RFC 1321.
' Copyright (C) Paul Johnston 1999 - 2000.
' Updated by Greg Holt 2000 - 2001.
' See [url="http://pajhome.org.uk/site/legal.html"]http://pajhome.org.uk/site/legal.html[/url] for details.

' CalcMD5("This is a test", MD5_Digest)
' Expected output with that input string = 'ce114e4501d2f4e2dcea3e17b546f339'

'==============================================
' INCLUDES and USING
'==============================================

'==============================================
' STANDARD DEFINES
'==============================================

#Define BEH_DEBUG_00
#If Defined( BEH_DEBUG_00)
#Include Once "windows.bi"
#Define dp( dbgTXT) OutputDebugString( dbgTXT)
#Else
#Define dp( dbgTXT) Print dbgTXT
#EndIf

'==============================================
' DECLARES
'==============================================

' Public functions.
Declare Sub CalcMD5 Cdecl Alias "CalcMD5" ( ByVal SourceStr As String, MD5Digest As ZString Ptr)

' Private functions.
Declare Function rhex( ByVal num As Long) As String
Declare Function rol( ByVal num As Long, ByVal cnt As Long) As Long
Declare Function Add32( x As Long, y As Long) As Long
Declare Function cmn( q As Long, a As Long, b As Long, x As Long, s As Long, t As Long) As Long
Declare Function ff( a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, t As Long) As Long
Declare Function gg( a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, t As Long) As Long
Declare Function hh( a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, t As Long) As Long
Declare Function ii( a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, t As Long) As Long

'=====================================================
' SCREEN SETUP
'=====================================================

'=====================================================
' INIT CODE
'=====================================================

'=====================================================
' FUNCTIONS
'=====================================================

'
' Rotate HEX.
' Convert a 32-Bit number to a hex string with the least significant byte first.
'
Function rhex ( ByVal num As Long) As String

Dim s As String
Dim t As String

s = Right$( "00000000" & Hex$( num), 8)
t = Right$( s,2) & Mid$( s,5,2) & Mid$( s,3,2) & Left$( s,2)
Function = t

End Function

'
' Rotate Bits Left
'
Function rol (ByVal num As Long, ByVal cnt As Long) As Long

Asm
  mov eax, [num]
  mov ecx, 0
  add ecx, [cnt]
  jz end_rol
more_rol:
  rol eax, 1
  Loop more_rol
end_rol:
  mov [Function], eax
End Asm

End Function

'
' Add integers, wrapping At 2^32. This uses 16-Bit operations internally
' to work around bugs in some JS interpreters.
'
Function Add32( x As Long, y As Long) As Long

Dim lsw As ULong
Dim lswy As ULong
Dim msw As ULong

lswy = (y And &HFFFF)
lsw = (x And &HFFFF) + lswy
msw = (x Shr 16) + (y Shr 16) + (lsw Shr 16)

Function = (msw Shl 16) Or (lsw And &HFFFF)

End Function

'
' Convert a string to a sequence of 16-Word blocks, stored as an array.
' Append padding bits and the length, as described in the MD5 standard.
'
Sub str2blks_MD5( strSrc As String, blks() As Long)

Dim nblk As Long
Dim i As Long

nblk = ((Len(strSrc) + 8) Shr 6) + 1
ReDim blks(nblk * 16)

For i = 0 To UBound(blks)
  blks(i) = 0
Next i

For i = 0 To (Len(strSrc)-1)
  blks(i Shr 2) = blks(i Shr 2) Or (Asc(Mid$(strSrc,i+1,1)) Shl ((i Mod 4) * 8))
Next

i = Len(strSrc)
blks(i Shr 2) = blks(i Shr 2) Or (&H80 Shl ((i Mod 4) * 8))
blks(nblk * 16 - 2) = Len(strSrc) * 8

End Sub

'
' These functions implement the basic operation for each round of the algorithm.
'
Function cmn( q As Long, a As Long, b As Long, x As Long, s As Long, t As Long) As Long
Function =  Add32( rol( Add32( Add32( a, q) , Add32( x, t)), s) , b)
End Function
Function ff( a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, t As Long) As Long
Function = cmn( (b And c) Or ((Not(b)) And d), a, b, x, s, t)
End Function
Function gg( a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, t As Long) As Long
Function = cmn( (b And d) Or (c And (Not(d))), a, b, x, s, t)
End Function
Function hh( a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, t As Long) As Long
Function = cmn( b Xor c Xor d, a, b, x, s, t)
End Function
Function ii( a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, t As Long) As Long
Function = cmn( c Xor (b Or Not(d)), a, b, x, s, t)
End Function

'
' CalcMD5() is the entry point for the MD5 routine.
'
Sub CalcMD5 Cdecl Alias "CalcMD5" ( ByVal SourceStr As String, MD5Digest As ZString Ptr) Export

Dim a As Long
Dim b As Long
Dim c As Long
Dim d As Long
Dim olda As Long
Dim oldb As Long
Dim oldc As Long
Dim oldd As Long
Dim i As Long
Dim x() As Long

a = 1732584193
b = -271733879
c = -1732584194
d = 271733878

ReDim x(1)

str2blks_MD5 SourceStr, x()

For i = 0 To UBound(x)-1 Step 16

  olda = a
  oldb = b
  oldc = c
  oldd = d

  a = ff(a, b, c, d, x(i+ 0), 7 , -680876936)
  d = ff(d, a, b, c, x(i+ 1), 12, -389564586)
  c = ff(c, d, a, b, x(i+ 2), 17,  606105819)
  b = ff(b, c, d, a, x(i+ 3), 22, -1044525330)
  a = ff(a, b, c, d, x(i+ 4), 7 , -176418897)
  d = ff(d, a, b, c, x(i+ 5), 12,  1200080426)
  c = ff(c, d, a, b, x(i+ 6), 17, -1473231341)
  b = ff(b, c, d, a, x(i+ 7), 22, -45705983)
  a = ff(a, b, c, d, x(i+ 8), 7 ,  1770035416)
  d = ff(d, a, b, c, x(i+ 9), 12, -1958414417)
  c = ff(c, d, a, b, x(i+10), 17, -42063)
  b = ff(b, c, d, a, x(i+11), 22, -1990404162)
  a = ff(a, b, c, d, x(i+12), 7 ,  1804603682)
  d = ff(d, a, b, c, x(i+13), 12, -40341101)
  c = ff(c, d, a, b, x(i+14), 17, -1502002290)
  b = ff(b, c, d, a, x(i+15), 22,  1236535329)

  a = gg(a, b, c, d, x(i+ 1), 5 , -165796510)
  d = gg(d, a, b, c, x(i+ 6), 9 , -1069501632)
  c = gg(c, d, a, b, x(i+11), 14,  643717713)
  b = gg(b, c, d, a, x(i+ 0), 20, -373897302)
  a = gg(a, b, c, d, x(i+ 5), 5 , -701558691)
  d = gg(d, a, b, c, x(i+10), 9 ,  38016083)
  c = gg(c, d, a, b, x(i+15), 14, -660478335)
  b = gg(b, c, d, a, x(i+ 4), 20, -405537848)
  a = gg(a, b, c, d, x(i+ 9), 5 ,  568446438)
  d = gg(d, a, b, c, x(i+14), 9 , -1019803690)
  c = gg(c, d, a, b, x(i+ 3), 14, -187363961)
  b = gg(b, c, d, a, x(i+ 8), 20,  1163531501)
  a = gg(a, b, c, d, x(i+13), 5 , -1444681467)
  d = gg(d, a, b, c, x(i+ 2), 9 , -51403784)
  c = gg(c, d, a, b, x(i+ 7), 14,  1735328473)
  b = gg(b, c, d, a, x(i+12), 20, -1926607734)

  a = hh(a, b, c, d, x(i+ 5), 4 , -378558)
  d = hh(d, a, b, c, x(i+ 8), 11, -2022574463)
  c = hh(c, d, a, b, x(i+11), 16,  1839030562)
  b = hh(b, c, d, a, x(i+14), 23, -35309556)
  a = hh(a, b, c, d, x(i+ 1), 4 , -1530992060)
  d = hh(d, a, b, c, x(i+ 4), 11,  1272893353)
  c = hh(c, d, a, b, x(i+ 7), 16, -155497632)
  b = hh(b, c, d, a, x(i+10), 23, -1094730640)
  a = hh(a, b, c, d, x(i+13), 4 ,  681279174)
  d = hh(d, a, b, c, x(i+ 0), 11, -358537222)
  c = hh(c, d, a, b, x(i+ 3), 16, -722521979)
  b = hh(b, c, d, a, x(i+ 6), 23,  76029189)
  a = hh(a, b, c, d, x(i+ 9), 4 , -640364487)
  d = hh(d, a, b, c, x(i+12), 11, -421815835)
  c = hh(c, d, a, b, x(i+15), 16,  530742520)
  b = hh(b, c, d, a, x(i+ 2), 23, -995338651)

  a = ii(a, b, c, d, x(i+ 0), 6 , -198630844)
  d = ii(d, a, b, c, x(i+ 7), 10,  1126891415)
  c = ii(c, d, a, b, x(i+14), 15, -1416354905)
  b = ii(b, c, d, a, x(i+ 5), 21, -57434055)
  a = ii(a, b, c, d, x(i+12), 6 ,  1700485571)
  d = ii(d, a, b, c, x(i+ 3), 10, -1894986606)
  c = ii(c, d, a, b, x(i+10), 15, -1051523)
  b = ii(b, c, d, a, x(i+ 1), 21, -2054922799)
  a = ii(a, b, c, d, x(i+ 8), 6 ,  1873313359)
  d = ii(d, a, b, c, x(i+15), 10, -30611744)
  c = ii(c, d, a, b, x(i+ 6), 15, -1560198380)
  b = ii(b, c, d, a, x(i+13), 21,  1309151649)
  a = ii(a, b, c, d, x(i+ 4), 6 , -145523070)
  d = ii(d, a, b, c, x(i+11), 10, -1120210379)
  c = ii(c, d, a, b, x(i+ 2), 15,  718787259)
  b = ii(b, c, d, a, x(i+ 9), 21, -343485551)

  a = Add32(a,olda)
  b = Add32(b,oldb)
  c = Add32(c,oldc)
  d = Add32(d,oldd)

Next i

*MD5Digest = rhex(a) & rhex(b) & rhex(c) & rhex(d)

End Sub

I've also attached a ZIP with the source code plus a compiled version of the DLL for those that don't want to build it themsleves.

Bruce Huber (cbruce)

MD5_Hash.zip

Edited by cbruce
Link to comment
Share on other sites

Thanks a lot cbruce. This is very usefull !!

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...