Link to home
Start Free TrialLog in
Avatar of rkulp
rkulpFlag for United States of America

asked on

VB6.CopyArray Question

I have tried to converet Fresle's CGenericRegistration and CMD5 classes from VB6 to VB.Net 2005. (www.frez.co.uk/registration.zip)  The wizard converts the TestRegistration program, which includes the classes and two others, and runs fine when AscB is replaced with Asc, although the results are not the same. The wizard inserts the following code in the ConvertToWordArray function:

ConvertToWordArray = vb6.copyarray (lWordArray)

This works great when run in the IDE but when the classes are put into a class library this line gives a "VB6 not defined" type error.
The following import statement is in both the TestRegistration program and the Class Library project:

Imports VB = Microsoft.VisualBasic

I have been unable to find where the VB6.CopyArray method is located or what method is available to duplicate the functionality.
Any help would be greatly appreciated. Both VB6 and VB.Net 2005 versions follow.

*******************************************************************
VB6 code:

Private Function ConvertToWordArray(sMessage As String) As Long()
    Dim lMessageLength  As Long
    Dim lNumberOfWords  As Long
    Dim lWordArray()    As Long
    Dim lBytePosition   As Long
    Dim lByteCount      As Long
    Dim lWordCount      As Long
    Dim lChar           As Long
   
    Const MODULUS_BITS      As Long = 512
    Const CONGRUENT_BITS    As Long = 448
   
    lMessageLength = Len(sMessage)
   
    ' Get padded number of words. Message needs to be congruent to 448 bits,
    ' modulo 512 bits. If it is exactly congruent to 448 bits, modulo 512 bits
    ' it must still have another 512 bits added. 512 bits = 64 bytes
    ' (or 16 * 4 byte words), 448 bits = 56 bytes. This means lMessageSize must
    ' be a multiple of 16 (i.e. 16 * 4 (bytes) * 8 (bits))
    lNumberOfWords = (((lMessageLength + _
        ((MODULUS_BITS - CONGRUENT_BITS) \ BITS_TO_A_BYTE)) \ _
        (MODULUS_BITS \ BITS_TO_A_BYTE)) + 1) * _
        (MODULUS_BITS \ BITS_TO_A_WORD)
    ReDim lWordArray(lNumberOfWords - 1)
   
    ' Combine each block of 4 bytes (ascii code of character) into one long
    ' value and store in the message. The high-order (most significant) bit of
    ' each byte is listed first. However, the low-order (least significant) byte
    ' is given first in each word.
    lBytePosition = 0
    lByteCount = 0
    Do Until lByteCount >= lMessageLength
        ' Each word is 4 bytes
        lWordCount = lByteCount \ BYTES_TO_A_WORD
               
        ' The bytes are put in the word from the right most edge
        lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE
        lChar = AscB(Mid(sMessage, lByteCount + 1, 1))
        lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(lChar, lBytePosition)
        lByteCount = lByteCount + 1
    Loop

    ' Terminate according to MD5 rules with a 1 bit, zeros and the length in
    ' bits stored in the last two words
    lWordCount = lByteCount \ BYTES_TO_A_WORD
    lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE

    ' Add a terminating 1 bit, all the rest of the bits to the end of the
    ' word array will default to zero
    lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(&H80, lBytePosition)

    ' We put the length of the message in bits into the last two words, to get
    ' the length in bits we need to multiply by 8 (or left shift 3). This left
    ' shifted value is put in the first word. Any bits shifted off the left edge
    ' need to be put in the second word, we can work out which bits by shifting
    ' right the length by 29 bits.
    lWordArray(lNumberOfWords - 2) = LShift(lMessageLength, 3)
    lWordArray(lNumberOfWords - 1) = RShift(lMessageLength, 29)
   
    ConvertToWordArray = lWordArray
End Function

******************************************************
VB.Net 2005 Code:

      Private Function ConvertToWordArray(ByRef sMessage As String) As Integer()
            Dim lMessageLength As Integer
            Dim lNumberOfWords As Integer
            Dim lWordArray() As Integer
            Dim lBytePosition As Integer
            Dim lByteCount As Integer
            Dim lWordCount As Integer
            Dim lChar As Integer
            
            Const MODULUS_BITS As Integer = 512
            Const CONGRUENT_BITS As Integer = 448
            
            lMessageLength = Len(sMessage)
            
            ' Get padded number of words. Message needs to be congruent to 448 bits,
            ' modulo 512 bits. If it is exactly congruent to 448 bits, modulo 512 bits
            ' it must still have another 512 bits added. 512 bits = 64 bytes
            ' (or 16 * 4 byte words), 448 bits = 56 bytes. This means lMessageSize must
            ' be a multiple of 16 (i.e. 16 * 4 (bytes) * 8 (bits))
            lNumberOfWords = (((lMessageLength + ((MODULUS_BITS - CONGRUENT_BITS) \ BITS_TO_A_BYTE)) \ (MODULUS_BITS \ BITS_TO_A_BYTE)) + 1) * (MODULUS_BITS \ BITS_TO_A_WORD)
            ReDim lWordArray(lNumberOfWords - 1)
            
            ' Combine each block of 4 bytes (ascii code of character) into one long
            ' value and store in the message. The high-order (most significant) bit of
            ' each byte is listed first. However, the low-order (least significant) byte
            ' is given first in each word.
            lBytePosition = 0
            lByteCount = 0
            Do Until lByteCount >= lMessageLength
                  ' Each word is 4 bytes
                  lWordCount = lByteCount \ BYTES_TO_A_WORD
                  
                  ' The bytes are put in the word from the right most edge
                  lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE
            ' lChar = AscB(Mid(sMessage, lByteCount + 1, 1)) AscB no longer supported.
            lChar = Asc(Mid(sMessage, lByteCount + 1, 1))

            lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(lChar, lBytePosition)
                  lByteCount = lByteCount + 1
            Loop
            
            ' Terminate according to MD5 rules with a 1 bit, zeros and the length in
            ' bits stored in the last two words
            lWordCount = lByteCount \ BYTES_TO_A_WORD
            lBytePosition = (lByteCount Mod BYTES_TO_A_WORD) * BITS_TO_A_BYTE
            
            ' Add a terminating 1 bit, all the rest of the bits to the end of the
            ' word array will default to zero
            lWordArray(lWordCount) = lWordArray(lWordCount) Or LShift(&H80s, lBytePosition)
            
            ' We put the length of the message in bits into the last two words, to get
            ' the length in bits we need to multiply by 8 (or left shift 3). This left
            ' shifted value is put in the first word. Any bits shifted off the left edge
            ' need to be put in the second word, we can work out which bits by shifting
            ' right the length by 29 bits.
            lWordArray(lNumberOfWords - 2) = LShift(lMessageLength, 3)
            lWordArray(lNumberOfWords - 1) = RShift(lMessageLength, 29)
            
        ConvertToWordArray = VB6.CopyArray(lWordArray)

      End Function
Avatar of Hillwaaa
Hillwaaa
Flag of Australia image

Hi rkulp,

You will probably need to use the following import instead (this gives you the VB6 stuff)

Imports Microsoft.VisualBasic.Compatibility

note that you will need to add a project reference to the "Microsoft Visual Basic .NET Compatibility Runtime".

Cheers!
Avatar of rkulp

ASKER

Hilwaaa,

Thanks for the suggestion. Unfortunately, that did not resolve the problem, but I am sure you are on the right track. Going down to the VisualBasic.Compatibility.VB6 namespace did not help as CopyArray is not in the namespace.

I did some more testing this morning and discovered what I should have discovered at first:

ConvertToWordArray = lWordArray

and

ConvertToWordArray = VB6.CopyArray(lWordArray)

yielded exactly the same ConvertToWordArray result.  That meant the problem was really in the calling program. I found it and all is now well.

I will close this question even though it means I may never know where VB6.CopyArray really exists.
ASKER CERTIFIED SOLUTION
Avatar of Hillwaaa
Hillwaaa
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of rkulp

ASKER

Hillwaaa:

I stand corrected. It did not appear in my VB 2005 Express IDE. My professional edition is in transit. Thanks for your help.
Ah - that's great.  Good luck with the rest of your conversion! (they can be fun :)
Avatar of rkulp

ASKER

I stand corrected again. I found it in the Express IDE. The imports statement should be:

Imports VB6 = Microsoft.VisualBasic.Compatibility.VB6

Then VB6.CopyArray will work (or you could use the fully-qualified name rather than the alias VB6)

Thanks for the encouragement. The original program is about 40,000 lines. I will try to re-write much of it in a simpler form. Great fun.