pcuser_tom Posted August 3, 2006 Share Posted August 3, 2006 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 HEREThe 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 LongPrivate Declare Function MD5Translate Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByRef MySum As MDxSum) As LongPrivate Declare Function MDxFinalize Lib "mdx.dll" (ByRef MySum As MDxSum) As LongPrivate Declare Function MDxGetVersion Lib "mdx.dll" () As LongPrivate Declare Function MDxInit Lib "mdx.dll" (ByRef MySum As MDxSum) As LongPrivate Declare Function MDxPad Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByVal MyLong As Long) As LongType MDxSum dwSum(3) As LongEnd TypeDim MyFile As StringDim md5DataSum As MDxSumDim lpData As StringPublic Function GetHash(fName As String)MyFile = fNameMDxInit md5DataSumIf FileLen(MyFile) = 0 Then Exit FunctionOpen 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 IfClose #1End FunctionThis 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 More sharing options...
Siginet Posted August 4, 2006 Share Posted August 4, 2006 I don't know vb very well... but I am good with autoit.Is there some sort of sleep command? Link to comment Share on other sites More sharing options...
LLXX Posted August 4, 2006 Share Posted August 4, 2006 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 LongEnd 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 More sharing options...
RogueSpear Posted August 4, 2006 Share Posted August 4, 2006 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 More sharing options...
jdoe Posted August 4, 2006 Share Posted August 4, 2006 Type MDxSum dwSum(3) As LongEnd 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 fileMDxSum STRUCT dwSum1 dd 0 dwSum2 dd 0 dwSum3 dd 0 dwSum4 dd 0MDxSum ENDS Link to comment Share on other sites More sharing options...
pcuser_tom Posted August 5, 2006 Author Share Posted August 5, 2006 (edited) paraglider pointed me in the right direction on another forum. I had to change:Dim lpData as StringtoDim lpData as String * 30000The above function is working fine now and produces an md5 hash for files (under 30k) as fast as I can feed them to itI 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 LongPrivate Declare Function MD5Translate Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByRef MySum As MDxSum) As LongPrivate Declare Function MDxFinalize Lib "mdx.dll" (ByRef MySum As MDxSum) As LongPrivate Declare Function MDxGetVersion Lib "mdx.dll" () As LongPrivate Declare Function MDxInit Lib "mdx.dll" (ByRef MySum As MDxSum) As LongPrivate Declare Function MDxPad Lib "mdx.dll" (ByVal MyString As String, ByVal MyLong As Long, ByVal MyLong As Long) As LongPrivate Type MDxSum dwSum(3) As LongEnd TypeDim md5DataSum As MDxSumDim lpData As String * 30000Dim MyFile As StringPrivate Function GetHash(fName As String)MyFile = fNameMDxInit md5DataSumIf FileLen(MyFile) = 0 Then Exit FunctionIf 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 FunctionEnd IfIf 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 NextEnd IfEnd FunctionPrivate Sub Form_Load()MsgBox GetHash("C:\ntdetect.com")EndEnd SubI'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 August 5, 2006 by pcuser_tom Link to comment Share on other sites More sharing options...
LLXX Posted August 5, 2006 Share Posted August 5, 2006 (edited) 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 August 5, 2006 by LLXX Link to comment Share on other sites More sharing options...
pcuser_tom Posted August 5, 2006 Author Share Posted August 5, 2006 (edited) 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 30kbThanks again for the help. Edited August 5, 2006 by pcuser_tom Link to comment Share on other sites More sharing options...
Tarun Posted August 5, 2006 Share Posted August 5, 2006 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 ExplicitPrivate lngTrack As LongPrivate arrLongConversion(4) As LongPrivate arrSplit64(63) As BytePrivate Const OFFSET_4 = 4294967296#Private Const MAXINT_4 = 2147483647Private Const S11 = 7Private Const S12 = 12Private Const S13 = 17Private Const S14 = 22Private Const S21 = 5Private Const S22 = 9Private Const S23 = 14Private Const S24 = 20Private Const S31 = 4Private Const S32 = 11Private Const S33 = 16Private Const S34 = 23Private Const S41 = 6Private Const S42 = 10Private Const S43 = 15Private Const S44 = 21Private 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 SelectEnd FunctionPrivate 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 = lngValueEnd FunctionPrivate 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 = strResultEnd FunctionPrivate 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 intLoop3End FunctionPrivate 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 = bytBufferEnd FunctionPrivate 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 SubPrivate 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 FunctionPrivate 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 FunctionPrivate 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 intByteIndexEnd SubPrivate 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 IfEnd FunctionPrivate 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, arrPaddingEnd SubPrivate 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 IfEnd FunctionPrivate Function MD5Value() As String MD5Value = LCase(MD5StringChange(arrLongConversion(1)) & MD5StringChange(arrLongConversion(2)) & MD5StringChange(arrLongConversion(3)) & MD5StringChange(arrLongConversion(4)))End FunctionPublic Function CalculateMD5(ByVal strMessage As String) As String Dim bytBuffer() As Byte bytBuffer = MD5StringArray(strMessage) MD5Start MD564Split Len(strMessage), bytBuffer MD5Finish CalculateMD5 = MD5ValueEnd FunctionPrivate 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 More sharing options...
pcuser_tom Posted August 5, 2006 Author Share Posted August 5, 2006 (edited) 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 August 5, 2006 by pcuser_tom Link to comment Share on other sites More sharing options...
Tarun Posted August 5, 2006 Share Posted August 5, 2006 I used to have to use my code to convert a special code to auth into a chat server. Link to comment Share on other sites More sharing options...
pcuser_tom Posted August 5, 2006 Author Share Posted August 5, 2006 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, 1MBvoid 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#endiftypedef 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 More sharing options...
LLXX Posted August 6, 2006 Share Posted August 6, 2006 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 More sharing options...
pcuser_tom Posted August 6, 2006 Author Share Posted August 6, 2006 Does VB have option to use an uninitialised array of bytes?noJust admit it, VB wasn't meant for these sort of applications...If I admit it, will you help me figure out what I'm doing wrong in my code? Link to comment Share on other sites More sharing options...
RogueSpear Posted August 6, 2006 Share Posted August 6, 2006 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now