kellyethridge / VBCorLib

The VBCorLib framework brings many of the powerful .NET classes to VB6.
http://www.kellyethridge.com/vbcorlib/
MIT License
112 stars 28 forks source link

MD5.ComputeHash is dropping a byte at the end of the result #89

Closed BluejacketScott closed 3 years ago

BluejacketScott commented 3 years ago

I'm submitting a bug report

Library Version: 3.1.0

Please tell us about your environment:

Operating System: Windows [10]

Current behavior: using VBCorLib.MD5.ComputeHash(Encoding.UTF8.GetBytes("TESTSTRING")) results in missing a single byte very near the end of the calculation. The correct hash is "64A1D290D85B4D1555DBE4B26374B401" but the library is returning "64A1D290D85B4D1555DBE4B26374B41" - it's missing a leading zero just before the last digit(1). Verified with another library and https://www.md5hashgenerator.com/ Expected/desired behavior: Result should not drop the last zero What is the expected behavior? Correct hash return What is the motivation / use case for changing the behavior? I'm using the MD5 to has an installation ID to create a unique and opaque token for each of my project's installation sites. I am happy to switch over to SHA1 or something else but I'd prefer to stay with MD5 (shorter hashes)

kellyethridge commented 3 years ago

ComputeHash returns a byte array, so I have to ask how are you displaying the result?

Using:

    Dim Hash() As Byte

    Hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("TESTSTRING"))

    Dim i As Long
    For i = LBound(Hash) To UBound(Hash)
        Debug.Print Object.ToString(Hash(i), "X2") & " ";
    Next

    Debug.Print

My result is 64 A1 D2 90 D8 5B 4D 15 55 DB E4 B2 63 74 B4 01. I placed spaces between each byte and explicitly show two characters each. Normal hex display will always trim leading zeros unless explicitly required.

BluejacketScott commented 3 years ago

``corlibhash = CorLibHasher.ComputeHash(Encoding.UTF8.GetBytes("TESTSTRING"))

Set sb = New StringBuilder
For x = LBound(corlibhash) To UBound(corlibhash)
    sb.Append Hex(corlibhash(x))
Next x

corlibresult = sb.ToString``

The difference between my code and yours is that I was calling Hex(corlibhash(x)) to convert the two bytes to hexidecimal. Didn't know that it would trim leading zeros. Also didn't know you could call Object.ToString out of the blue like that either. Learned something today!

kellyethridge commented 3 years ago

Yes, Object.ToString is the general method for converting a value to a string within the library. However, in your case if you're going to use StringBuilder to build your hex string consider using sb.AppendFormat "{0:X2}", Hash(x) in place of sb.Append Hex(Hash(x)).