Jump to content

Using an MD5 function from an external dll in VB6


Recommended Posts

I've been trying to write a routine in VB that calculates an md5 hash for every file in a directory and all sub directories and outputs the results into a txt file.

VB is WAY to slow to do anything like this but I found a dll called mdx.dll written in assembler by RudeBoy and is lightning fast! You can download his source files and binary dll HERE

The zip file includes an example C++ program to demonstrate how to use the dll. I made a vb6 module to interface the dll and it works great to calculate the md5 for a single file. My problem is that I'm usung FindFirstFile and FindNextFile api's to enumerate files very fast and feed them to the the function and it crashes the dll.

Here's my VB6 module to interface the dll.

Private Declare Function MD4Translate Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByRef MySum As MDxSum) As Long
Private Declare Function MD5Translate Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByRef MySum As MDxSum) As Long
Private Declare Function MDxFinalize Lib "mdx.dll" (ByRef MySum As MDxSum) As Long
Private Declare Function MDxGetVersion Lib "mdx.dll" () As Long
Private Declare Function MDxInit Lib "mdx.dll" (ByRef MySum As MDxSum) As Long
Private Declare Function MDxPad Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByVal MyLong As Long) As Long

Type MDxSum
dwSum(3) As Long
End Type

Dim MyFile As String
Dim md5DataSum As MDxSum
Dim lpData As String

Public Function GetHash(fName As String)

MyFile = fName
MDxInit md5DataSum

If FileLen(MyFile) = 0 Then Exit Function

Open MyFile For Binary As #1
If FileLen(MyFile) <= 30000 Then
lpData = Input(LOF(1), 1)
MDxPad lpData, FileLen(MyFile), FileLen(MyFile)
MD5Translate lpData, FileLen(MyFile), md5DataSum
MDxFinalize md5DataSum
GetHash = Hex(md5DataSum.dwSum(0)) & Hex(md5DataSum.dwSum(1)) & Hex(md5DataSum.dwSum(2)) & Hex(md5DataSum.dwSum(3))
Close #1
Exit Function
End If
Close #1
End Function

This code works great to hash a single file but crashes if I feed files to it too fast.

BTW. It currently only hashes files less than 30k so it can read the entire file at one time.

Can anyone compare my vb code to the sample C++ program that's included in the download to see what I'm doing wrong?

I also want to add the ability to "chunk" larger files but I need to figure out what I'm doing wrong with the basic function first.

Tom

Link to comment
Share on other sites


Worst thing to do is trying to read the whole file into memory at a time, because the file could be huge.

Read e.g. 65536 bytes at a time into a buffer, process those bytes, then continue reading in 64k blocks until EoF is reached.

I think you're already nearing the limits of VB as a language itself, may be time to move on to C/C++.

Type MDxSum
dwSum(3) As Long
End Type

...and shouldn't that be 4, not 3?

Also, how the program crashes is important also in figuring out the error. (Invalid Page Fault, Access Violation, Illegal Instruction, etc.)

Link to comment
Share on other sites

I don't know if you have any restrictions that are keeping you from upgrading from VB6 or not, but I posted a function in the sticky thread in this forum for generating MD5 sums on files. It leverages the built-in functionality provided by .NET. And it really doesn't matter what the file size is either.

Link to comment
Share on other sites

Type MDxSum
dwSum(3) As Long
End Type

...and shouldn't that be 4, not 3?

If Base 1 is not specified, dwSum(0), dwSum(1), dwSum(2) and dwSum(3) are the four Long needed.

From the include file

MDxSum STRUCT
dwSum1 dd 0
dwSum2 dd 0
dwSum3 dd 0
dwSum4 dd 0
MDxSum ENDS

Link to comment
Share on other sites

paraglider pointed me in the right direction on another forum. I had to change:

Dim lpData as String

to

Dim lpData as String * 30000

The above function is working fine now and produces an md5 hash for files (under 30k) as fast as I can feed them to it

I wanted to make sure the basic function was working with entire smaller files before moving on to splitting larger files and processing the chunks.

Now I'm having trouble with it not returning the correct md5 hash for larger files that were processed in chunks.

Here's the entire vb6 form that includes the all the code.

Private Declare Function MD4Translate Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByRef MySum As MDxSum) As Long
Private Declare Function MD5Translate Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByRef MySum As MDxSum) As Long
Private Declare Function MDxFinalize Lib "mdx.dll" (ByRef MySum As MDxSum) As Long
Private Declare Function MDxGetVersion Lib "mdx.dll" () As Long
Private Declare Function MDxInit Lib "mdx.dll" (ByRef MySum As MDxSum) As Long
Private Declare Function MDxPad Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByVal MyLong As Long) As Long
Private Type MDxSum
dwSum(3) As Long
End Type
Dim md5DataSum As MDxSum
Dim lpData As String * 30000
Dim MyFile As String

Private Function GetHash(fName As String)
MyFile = fName
MDxInit md5DataSum
If FileLen(MyFile) = 0 Then Exit Function
If FileLen(MyFile) <= 30000 Then
' The file is less than or equal to 30k
Open MyFile For Binary As #1
lpData = Input(LOF(1), 1)
Close #1
DoEvents
MDxInit md5DataSum
MDxPad lpData, FileLen(MyFile), FileLen(MyFile)
MD5Translate lpData, FileLen(MyFile), md5DataSum
MDxFinalize md5DataSum
GetHash = Hex(md5DataSum.dwSum(0)) & Hex(md5DataSum.dwSum(1)) & Hex(md5DataSum.dwSum(2)) & Hex(md5DataSum.dwSum(3))
Exit Function
End If
If FileLen(MyFile) > 30000 Then
' The file is greater that 30k - process it in 30k chunks
Open MyFile For Binary As #1
For i = 1 To LOF(1) Step 30000
DoEvents
If LOF(1) >= i + 30000 Then
lpData = Input(30000, 1)
MD5Translate lpData, Len(lpData), md5DataSum
Else
' There's less than 30k until the end of the file so
' pad it then call translate one more time then finish up
MDxPad lpData, Len(lpData), FileLen(MyFile)
MD5Translate lpData, Len(lpData), md5DataSum
MDxFinalize md5DataSum
GetHash = Hex(md5DataSum.dwSum(0)) & Hex(md5DataSum.dwSum(1)) & Hex(md5DataSum.dwSum(2)) & Hex(md5DataSum.dwSum(3))
Close #1
Exit Function
End If
Next
End If
End Function

Private Sub Form_Load()
MsgBox GetHash("C:\ntdetect.com")
End
End Sub

I'm sure it's something simple that I didn't translate correctly from the sample C++ program in the download but I can't figure out what it is. Any ideas?

Thanks for the link to the .NET code, I'm sure I'll be using it for alot of other projects that need a MD5 routine but this one can't be .NET and will need to be ran from PE/BartPE as well as windows.

Thanks for the help and suggestions so far.

Edited by pcuser_tom
Link to comment
Share on other sites

When programming, you should always use "round" numbers, i.e. powers of 2.

Reading the file in 32768 byte blocks would solve the problem, though I recommend 65536 since you will get better performance (approximately twice) without excessive memory usage.

The reason is, MD5 processes data in 64-byte (512 bit) blocks. 30000 is NOT divisible by 64, whereas every power of 2 greater than 64 is.

BTW, 30Kb is not 30000 bytes, it's 30720.

Edit: You should always see if someone else has already written what you're trying to accomplish, and probably written it better as well. http://md5deep.sourceforge.net/ <_<

Edited by LLXX
Link to comment
Share on other sites

The MDxPad function pads the string to be divisable by 64 (and returns the number of bytes that it padded) so it shouldn't matter if you pass it 30000, 32768 or 3.

A string in vb has a maximum value of 32768 so that's what I'm stuck with but that's ok.

I already have a vb routine that shells out to md5deep and captures the output but doing it like that is painfully slow, that's why I was looking for a dll to use as an alternative.

BTW. 30k isn't the same as 30kb

Thanks again for the help.

Edited by pcuser_tom
Link to comment
Share on other sites

If you need a working MD5 module for VB6, you can use this one. I developed it when I was on a Windows ME machine, so it might have some compile errors.

Option Explicit
Private lngTrack As Long
Private arrLongConversion(4) As Long
Private arrSplit64(63) As Byte
Private Const OFFSET_4 = 4294967296#
Private Const MAXINT_4 = 2147483647
Private Const S11 = 7
Private Const S12 = 12
Private Const S13 = 17
Private Const S14 = 22
Private Const S21 = 5
Private Const S22 = 9
Private Const S23 = 14
Private Const S24 = 20
Private Const S31 = 4
Private Const S32 = 11
Private Const S33 = 16
Private Const S34 = 23
Private Const S41 = 6
Private Const S42 = 10
Private Const S43 = 15
Private Const S44 = 21
Private Function MD5Round(strRound As String, a As Long, b As Long, c As Long, d As Long, x As Long, s As Long, ac As Long) As Long
Select Case strRound
Case Is = "FF"
a = MD5LongAdd4(a, (b And c) Or (Not (b) And d), x, ac)
a = MD5Rotate(a, s)
a = MD5LongAdd(a, b)
Case Is = "GG"
a = MD5LongAdd4(a, (b And d) Or (c And Not (d)), x, ac)
a = MD5Rotate(a, s)
a = MD5LongAdd(a, b)
Case Is = "HH"
a = MD5LongAdd4(a, b Xor c Xor d, x, ac)
a = MD5Rotate(a, s)
a = MD5LongAdd(a, b)
Case Is = "II"
a = MD5LongAdd4(a, c Xor (b Or Not (d)), x, ac)
a = MD5Rotate(a, s)
a = MD5LongAdd(a, b)
End Select
End Function
Private Function MD5Rotate(lngValue As Long, lngBits As Long) As Long
Dim lngSign As Long
Dim lngI As Long
lngBits = (lngBits Mod 32)
If lngBits = 0 Then MD5Rotate = lngValue: Exit Function
For lngI = 1 To lngBits
lngSign = lngValue And &HC0000000
lngValue = (lngValue And &H3FFFFFFF) * 2
lngValue = lngValue Or ((lngSign < 0) And 1) Or (CBool(lngSign And &H40000000) And &H80000000)
Next
MD5Rotate = lngValue
End Function
Private Function TRID() As String
Dim sngNum As Single, lngnum As Long
Dim strResult As String
sngNum = Rnd(2147483648#)
strResult = CStr(sngNum)
strResult = Replace(strResult, "0.", "")
strResult = Replace(strResult, ".", "")
strResult = Replace(strResult, "E-", "")
TRID = strResult
End Function
Private Function MD564Split(lngLength As Long, bytBuffer() As Byte) As String
Dim lngBytesTotal As Long, lngBytesToAdd As Long
Dim intLoop As Integer, intLoop2 As Integer, lngTrace As Long
Dim intInnerLoop As Integer, intLoop3 As Integer
lngBytesTotal = lngTrack Mod 64
lngBytesToAdd = 64 - lngBytesTotal
lngTrack = (lngTrack + lngLength)
If lngLength >= lngBytesToAdd Then
For intLoop = 0 To lngBytesToAdd - 1
arrSplit64(lngBytesTotal + intLoop) = bytBuffer(intLoop)
Next intLoop
MD5Conversion arrSplit64
lngTrace = (lngLength) Mod 64
For intLoop2 = lngBytesToAdd To lngLength - intLoop - lngTrace Step 64
For intInnerLoop = 0 To 63
arrSplit64(intInnerLoop) = bytBuffer(intLoop2 + intInnerLoop)
Next intInnerLoop
MD5Conversion arrSplit64
Next intLoop2
lngBytesTotal = 0
Else
intLoop2 = 0
End If
For intLoop3 = 0 To lngLength - intLoop2 - 1
arrSplit64(lngBytesTotal + intLoop3) = bytBuffer(intLoop2 + intLoop3)
Next intLoop3
End Function
Private Function MD5StringArray(strInput As String) As Byte()
Dim intLoop As Integer
Dim bytBuffer() As Byte
ReDim bytBuffer(Len(strInput))
For intLoop = 0 To Len(strInput) - 1
bytBuffer(intLoop) = Asc(Mid(strInput, intLoop + 1, 1))
Next intLoop
MD5StringArray = bytBuffer
End Function
Private Sub MD5Conversion(bytBuffer() As Byte)
Dim x(16) As Long, a As Long
Dim b As Long, c As Long
Dim d As Long
a = arrLongConversion(1)
b = arrLongConversion(2)
c = arrLongConversion(3)
d = arrLongConversion(4)
MD5Decode 64, x, bytBuffer
MD5Round "FF", a, b, c, d, x(0), S11, -680876936
MD5Round "FF", d, a, b, c, x(1), S12, -389564586
MD5Round "FF", c, d, a, b, x(2), S13, 606105819
MD5Round "FF", b, c, d, a, x(3), S14, -1044525330
MD5Round "FF", a, b, c, d, x(4), S11, -176418897
MD5Round "FF", d, a, b, c, x(5), S12, 1200080426
MD5Round "FF", c, d, a, b, x(6), S13, -1473231341
MD5Round "FF", b, c, d, a, x(7), S14, -45705983
MD5Round "FF", a, b, c, d, x(8), S11, 1770035416
MD5Round "FF", d, a, b, c, x(9), S12, -1958414417
MD5Round "FF", c, d, a, b, x(10), S13, -42063
MD5Round "FF", b, c, d, a, x(11), S14, -1990404162
MD5Round "FF", a, b, c, d, x(12), S11, 1804603682
MD5Round "FF", d, a, b, c, x(13), S12, -40341101
MD5Round "FF", c, d, a, b, x(14), S13, -1502002290
MD5Round "FF", b, c, d, a, x(15), S14, 1236535329
MD5Round "GG", a, b, c, d, x(1), S21, -165796510
MD5Round "GG", d, a, b, c, x(6), S22, -1069501632
MD5Round "GG", c, d, a, b, x(11), S23, 643717713
MD5Round "GG", b, c, d, a, x(0), S24, -373897302
MD5Round "GG", a, b, c, d, x(5), S21, -701558691
MD5Round "GG", d, a, b, c, x(10), S22, 38016083
MD5Round "GG", c, d, a, b, x(15), S23, -660478335
MD5Round "GG", b, c, d, a, x(4), S24, -405537848
MD5Round "GG", a, b, c, d, x(9), S21, 568446438
MD5Round "GG", d, a, b, c, x(14), S22, -1019803690
MD5Round "GG", c, d, a, b, x(3), S23, -187363961
MD5Round "GG", b, c, d, a, x(8), S24, 1163531501
MD5Round "GG", a, b, c, d, x(13), S21, -1444681467
MD5Round "GG", d, a, b, c, x(2), S22, -51403784
MD5Round "GG", c, d, a, b, x(7), S23, 1735328473
MD5Round "GG", b, c, d, a, x(12), S24, -1926607734
MD5Round "HH", a, b, c, d, x(5), S31, -378558
MD5Round "HH", d, a, b, c, x(8), S32, -2022574463
MD5Round "HH", c, d, a, b, x(11), S33, 1839030562
MD5Round "HH", b, c, d, a, x(14), S34, -35309556
MD5Round "HH", a, b, c, d, x(1), S31, -1530992060
MD5Round "HH", d, a, b, c, x(4), S32, 1272893353
MD5Round "HH", c, d, a, b, x(7), S33, -155497632
MD5Round "HH", b, c, d, a, x(10), S34, -1094730640
MD5Round "HH", a, b, c, d, x(13), S31, 681279174
MD5Round "HH", d, a, b, c, x(0), S32, -358537222
MD5Round "HH", c, d, a, b, x(3), S33, -722521979
MD5Round "HH", b, c, d, a, x(6), S34, 76029189
MD5Round "HH", a, b, c, d, x(9), S31, -640364487
MD5Round "HH", d, a, b, c, x(12), S32, -421815835
MD5Round "HH", c, d, a, b, x(15), S33, 530742520
MD5Round "HH", b, c, d, a, x(2), S34, -995338651
MD5Round "II", a, b, c, d, x(0), S41, -198630844
MD5Round "II", d, a, b, c, x(7), S42, 1126891415
MD5Round "II", c, d, a, b, x(14), S43, -1416354905
MD5Round "II", b, c, d, a, x(5), S44, -57434055
MD5Round "II", a, b, c, d, x(12), S41, 1700485571
MD5Round "II", d, a, b, c, x(3), S42, -1894986606
MD5Round "II", c, d, a, b, x(10), S43, -1051523
MD5Round "II", b, c, d, a, x(1), S44, -2054922799
MD5Round "II", a, b, c, d, x(8), S41, 1873313359
MD5Round "II", d, a, b, c, x(15), S42, -30611744
MD5Round "II", c, d, a, b, x(6), S43, -1560198380
MD5Round "II", b, c, d, a, x(13), S44, 1309151649
MD5Round "II", a, b, c, d, x(4), S41, -145523070
MD5Round "II", d, a, b, c, x(11), S42, -1120210379
MD5Round "II", c, d, a, b, x(2), S43, 718787259
MD5Round "II", b, c, d, a, x(9), S44, -343485551
arrLongConversion(1) = MD5LongAdd(arrLongConversion(1), a)
arrLongConversion(2) = MD5LongAdd(arrLongConversion(2), b)
arrLongConversion(3) = MD5LongAdd(arrLongConversion(3), c)
arrLongConversion(4) = MD5LongAdd(arrLongConversion(4), d)
End Sub
Private Function MD5LongAdd(lngVal1 As Long, lngVal2 As Long) As Long
Dim lngHighWord As Long
Dim lngLowWord As Long
Dim lngOverflow As Long
lngLowWord = (lngVal1 And &HFFFF&) + (lngVal2 And &HFFFF&)
lngOverflow = lngLowWord \ 65536
lngHighWord = (((lngVal1 And &HFFFF0000) \ 65536) + ((lngVal2 And &HFFFF0000) \ 65536) + lngOverflow) And &HFFFF&
MD5LongAdd = MD5LongConversion((lngHighWord * 65536#) + (lngLowWord And &HFFFF&))
End Function
Private Function MD5LongAdd4(lngVal1 As Long, lngVal2 As Long, lngVal3 As Long, lngVal4 As Long) As Long
Dim lngHighWord As Long
Dim lngLowWord As Long
Dim lngOverflow As Long
lngLowWord = (lngVal1 And &HFFFF&) + (lngVal2 And &HFFFF&) + (lngVal3 And &HFFFF&) + (lngVal4 And &HFFFF&)
lngOverflow = lngLowWord \ 65536
lngHighWord = (((lngVal1 And &HFFFF0000) \ 65536) + ((lngVal2 And &HFFFF0000) \ 65536) + ((lngVal3 And &HFFFF0000) \ 65536) + ((lngVal4 And &HFFFF0000) \ 65536) + lngOverflow) And &HFFFF&
MD5LongAdd4 = MD5LongConversion((lngHighWord * 65536#) + (lngLowWord And &HFFFF&))
End Function
Private Sub MD5Decode(intLength As Integer, lngOutBuffer() As Long, bytInBuffer() As Byte)
Dim intDblIndex As Integer
Dim intByteIndex As Integer
Dim dblSum As Double
intDblIndex = 0
For intByteIndex = 0 To intLength - 1 Step 4
dblSum = bytInBuffer(intByteIndex) + bytInBuffer(intByteIndex + 1) * 256# + bytInBuffer(intByteIndex + 2) * 65536# + bytInBuffer(intByteIndex + 3) * 16777216#
lngOutBuffer(intDblIndex) = MD5LongConversion(dblSum)
intDblIndex = (intDblIndex + 1)
Next intByteIndex
End Sub
Private Function MD5LongConversion(dblValue As Double) As Long
If dblValue < 0 Or dblValue >= OFFSET_4 Then Error 6
If dblValue <= MAXINT_4 Then
MD5LongConversion = dblValue
Else
MD5LongConversion = dblValue - OFFSET_4
End If
End Function
Private Sub MD5Finish()
Dim dblBits As Double
Dim arrPadding(72) As Byte
Dim lngBytesBuffered As Long
arrPadding(0) = &H80
dblBits = lngTrack * 8
lngBytesBuffered = lngTrack Mod 64
If lngBytesBuffered <= 56 Then
MD564Split (56 - lngBytesBuffered), arrPadding
Else
MD564Split (120 - lngTrack), arrPadding
End If
arrPadding(0) = MD5LongConversion(dblBits) And &HFF&
arrPadding(1) = MD5LongConversion(dblBits) \ 256 And &HFF&
arrPadding(2) = MD5LongConversion(dblBits) \ 65536 And &HFF&
arrPadding(3) = MD5LongConversion(dblBits) \ 16777216 And &HFF&
arrPadding(4) = 0
arrPadding(5) = 0
arrPadding(6) = 0
arrPadding(7) = 0
MD564Split 8, arrPadding
End Sub
Private Function MD5StringChange(lngnum As Long) As String
Dim bytA As Byte
Dim bytB As Byte
Dim bytC As Byte
Dim bytD As Byte
bytA = lngnum And &HFF&
If bytA < 16 Then
MD5StringChange = "0" & Hex(bytA)
Else
MD5StringChange = Hex(bytA)
End If
bytB = (lngnum And &HFF00&) \ 256
If bytB < 16 Then
MD5StringChange = MD5StringChange & "0" & Hex(bytB)
Else
MD5StringChange = MD5StringChange & Hex(bytB)
End If
bytC = (lngnum And &HFF0000) \ 65536
If bytC < 16 Then
MD5StringChange = MD5StringChange & "0" & Hex(bytC)
Else
MD5StringChange = MD5StringChange & Hex(bytC)
End If
If lngnum < 0 Then
bytD = ((lngnum And &H7F000000) \ 16777216) Or &H80&
Else
bytD = (lngnum And &HFF000000) \ 16777216
End If
If bytD < 16 Then
MD5StringChange = MD5StringChange & "0" & Hex(bytD)
Else
MD5StringChange = MD5StringChange & Hex(bytD)
End If
End Function
Private Function MD5Value() As String
MD5Value = LCase(MD5StringChange(arrLongConversion(1)) & MD5StringChange(arrLongConversion(2)) & MD5StringChange(arrLongConversion(3)) & MD5StringChange(arrLongConversion(4)))
End Function
Public Function CalculateMD5(ByVal strMessage As String) As String
Dim bytBuffer() As Byte
bytBuffer = MD5StringArray(strMessage)
MD5Start
MD564Split Len(strMessage), bytBuffer
MD5Finish
CalculateMD5 = MD5Value
End Function
Private Sub MD5Start()
lngTrack = 0
arrLongConversion(1) = MD5LongConversion(1732584193#)
arrLongConversion(2) = MD5LongConversion(4023233417#)
arrLongConversion(3) = MD5LongConversion(2562383102#)
arrLongConversion(4) = MD5LongConversion(271733878#)
End Sub

Link to comment
Share on other sites

Thanks for sharing your code Tarun. I haven't tried it yet but I already have an md5 module but it's way too slow. I'm going to be hashing about 4,000 files and some of them are 5-8mb in size. I try out your module though.

Edited by pcuser_tom
Link to comment
Share on other sites

Here's the example C++ program with the DigestFile( char *szFName ) function that I'm trying to convert to vb.

#include "mdx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// READLEN % 64 must = 0
#define READLEN 1048576L // 2^20, 1MB

void DigestFile( char * );
void DigestString();

void main(int argc, char *argv[])
{
printf("%s\n\n", MDxGetVersion());

if( argc > 1 )
DigestFile( argv[1] );
else
DigestString();

}

/*
I use the 'chunk' method for processing files not because of
limitations of my dll, but think what would happen if you
tried to load an entire cd image into memory.
*/
void DigestFile( char *szFName )
{
FILE *file;
void *lpData;
long flen, mlen;
MDxSum mdDataSum;
MDxSum md4DataSum;

// the 64 is for padding purposes
lpData = malloc( READLEN + 64 );

printf( "MD4/5 Digests of \"%s\":\n", szFName );

file = fopen( szFName, "rb" );
if( file == NULL )
{
printf("ERROR: File not found.\n");
return;
}

MDxInit( &mdDataSum );
MDxInit( &md4DataSum );

fseek( file, 0, SEEK_END );
//Get the file length
flen = mlen = ftell( file );
fseek( file, 0, SEEK_SET );

// When it takes a while to process a large file,
// remember that for each chunk it has to run
// through the main translation loop 16384 times!

printf("Processing %ld byte file: .", flen );

while( flen > READLEN )
{
if( fread( lpData, 1, READLEN, file ) != READLEN)
{
printf("READ ERROR!\n");
return;
}
MD5Translate( lpData, READLEN, &mdDataSum );
MD4Translate( lpData, READLEN, &md4DataSum );
flen -= READLEN;
printf(".");
}

if (fread( lpData, 1, flen, file ) != flen)
{
printf("READ ERROR!\n");
return;
}
// This is why I added the new argument to MDxPad
// So we can pass the length of the data AND the
// Total length of the message
// Also it now returns the # of padding bytes added,
// this is for files that are an exact multiple of the chunk
// length. (Otherwise the padding isn't Translated)
flen += MDxPad( lpData, flen, mlen );
MD5Translate( lpData, flen, &mdDataSum );
MD4Translate( lpData, flen, &md4DataSum );

// New step necessary because of the 'chunking' method
MDxFinalize( &mdDataSum );
MDxFinalize( &md4DataSum );

printf("\nMD4: %08x%08x%08x%08x\n", md4DataSum.dwSum[0], md4DataSum.dwSum[1], md4DataSum.dwSum[2], md4DataSum.dwSum[3]);
printf("MD5: %08x%08x%08x%08x\n", mdDataSum.dwSum[0], mdDataSum.dwSum[1], mdDataSum.dwSum[2], mdDataSum.dwSum[3]);
fclose(file);

}

void DigestString()
{

//For our demo purposes, no strings bigger than 1024 :)
unsigned char lpData[1024] = "";
long len = 0;
MDxSum mdDataSum;

printf("Enter the string to digest: ");
scanf("%s", &lpData );
len = strlen(lpData);

// Have to do this before the Padding...well...it's best anyway;)
printf( "MD4/5 Digests of \n\"%s\":\n", lpData );

// For the strings, we're gonna pad and digest the string
// in one pass.
MDxInit( &mdDataSum );
MDxPad( lpData, len, len );

MD5Translate( lpData, len, &mdDataSum );
// New step necessary because of the 'chunking' method
MDxFinalize( &mdDataSum );
printf("MD5: %08x%08x%08x%08x\n", mdDataSum.dwSum[0], mdDataSum.dwSum[1], mdDataSum.dwSum[2], mdDataSum.dwSum[3]);

MDxInit( &mdDataSum );
MD4Translate( lpData, len, &mdDataSum );
printf("MD4: %08x%08x%08x%08x\n", mdDataSum.dwSum[0], mdDataSum.dwSum[1], mdDataSum.dwSum[2], mdDataSum.dwSum[3]);

return;
}

and the include file:

#ifndef __windows_h__
typedef unsigned long DWORD;
#define STDCALL _stdcall
#endif

typedef struct
{
DWORD dwSum[4];
}MDxSum;

DWORD STDCALL MDxPad ( unsigned char *, unsigned long, unsigned long );
void STDCALL MDxInit( MDxSum * );
void STDCALL MD5Translate( unsigned char *, long, MDxSum * );
void STDCALL MD4Translate( unsigned char *, long, MDxSum * );
const char * STDCALL MDxGetVersion();
void STDCALL MDxFinalize( MDxSum * );

Link to comment
Share on other sites

A string in vb has a maximum value of 32768 so that's what I'm stuck with but that's ok.
Does VB have option to use an uninitialised array of bytes?

Just admit it, VB wasn't meant for these sort of applications...

Link to comment
Share on other sites

I just got into VB starting with the 2005 version, so I can't be of that much assistance here, but perhaps you could translate what I wrote to work with VB6. Granted it's relying on a .NET feature, but I'm wondering if you could more or less replace the .NET stuff with the .dll file you want to use.

I'm running that function against 100MB+ files just as fast as HashTab does it.

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
  • Recently Browsing   0 members

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