1

I have this bit of t-sql code

set @UrlHash = convert(bigint, hashbytes('MD5', @Url))  

I wonder if I can write a function in C# which returns me the exact same hash as the line above without going to SQL.

Is it possible?

Requirement is that C# MUST created exact same hash.

5
  • 2
    Curious given that an MD5 hash is 128-bit and a bigint is 64-bit how does this even work? Commented Feb 26, 2013 at 13:48
  • There is an MD5 class which implements the MD5 hash algorithm. That sounds like what your looking for. Commented Feb 26, 2013 at 13:50
  • Check out System.Security.Cryptography.MD5 Commented Feb 26, 2013 at 13:50
  • ok. but how about the convert bigint piece? even if I get a byte array from the MD5 hash... how will the convert and bigint piece workout? Commented Feb 26, 2013 at 14:12
  • Looks like it might be an endian issue: stackoverflow.com/q/8467072/21727 Commented Feb 26, 2013 at 15:50

3 Answers 3

7

The select

SELECT CONVERT(BIGINT, HASHBYTES('MD5', 'http://stackoverflow.com')) 

will yield the following result:

-3354682182756996262

If you now try to create a MD5 hash in C#

MD5 md5 = MD5.Create();
byte[] textToHash = Encoding.UTF8.GetBytes("http://stackoverflow.com");
byte[] result = md5.ComputeHash(textToHash); 
long numeric = BitConverter.ToInt64(result, 0);

numeric will be 8957512937738269783.


So what's the issue (besides the fact that a MD5 hash is 128-bit and BIGINT/long is just 64-bit)?

It's an endian issue (the bytes are in the wrong order). Let's fix it using the BitConverter class and reverse the bytes as needed:

MD5 md5 = MD5.Create();
byte[] textToHash = Encoding.UTF8.GetBytes("http://stackoverflow.com");
byte[] result = md5.ComputeHash(textToHash); 

if (BitConverter.IsLittleEndian)
    Array.Reverse(result);

long numeric = BitConverter.ToInt64(result, 0);

numeric is now -3354682182756996262 as you want.

Sign up to request clarification or add additional context in comments.

1 Comment

I missed that mbeckish already found a possible duplicate: SQL Server varbinary bigint with BitConverter.ToInt64 values are different
0

You should use MD5 class, here is the example from http://blogs.msdn.com/b/csharpfaq/archive/2006/10/09/how-do-i-calculate-a-md5-hash-from-a-string_3f00_.aspx, with output as int 64 :

public int64 CalculateMD5Hash(string input)
{
    // step 1, calculate MD5 hash from input
    MD5 md5 = System.Security.Cryptography.MD5.Create();
    byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
    byte[] hash = md5.ComputeHash(inputBytes);

    return BitConverter.ToInt64(hash, 0);
}

3 Comments

and what about the covert function? we cannot cast the byte[] into a Int64. can we?
but the hashes don't match if you pass google.com to the code about (instead of ASCII I use unicode) it produces -5931442742085820074 whereas t-sql produces -7038863548646352319 select convert(bigint, hashbytes('MD5', N'google.com')
Sorry the hashes match till at the level of MD5 creation... but when we convert to bigint ... at that point of time the numbers differ.
-1

Isn't an MD5 hash standard? Can't you use a standard MD5 C# implementation? What about using the code in here?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.