MD5CryptoServiceProvider's ComputeHash doesn't match (x86 vs x64)?
-
Hi All Hopefully someone can help shed some light for me. I have some code I have used for years to calculate and store (in SQL Server database), and retrieve and compare a hash value using ComputeHash of the MD5CryptoServiceProvider. I have recently upgraded to x64 (Windows 7) from x86 (Vista) but now my hashes calculated on the x86 does not match when compared (using x64)! (Hope that all makes sense.) Is there any obvious reasons for this? Where should I be looking?? thanx
-
Hi All Hopefully someone can help shed some light for me. I have some code I have used for years to calculate and store (in SQL Server database), and retrieve and compare a hash value using ComputeHash of the MD5CryptoServiceProvider. I have recently upgraded to x64 (Windows 7) from x86 (Vista) but now my hashes calculated on the x86 does not match when compared (using x64)! (Hope that all makes sense.) Is there any obvious reasons for this? Where should I be looking?? thanx
Well, I think I have narrowed it down to the "GetHashCode" being the culprit! After replacing the "GetHashCode" with my own hash function it seems to work in both x86 and x64 OSs.
For Each c As DataColumn In ds.Tables("mytable").Columns
If Not c.ColumnName = "hashvalue" ThenIf r(c) IsNot DBNull.Value Then RowHash += r(c).**GetHashCode**.ToString End If
Next
' ... compare the "RowHash" with the one stored in the "hashvalue" column ...
This article seem to agree. "... the .NET Object.GetHashCode() method, which unfortunately differs between x86 and x64 systems." Any have any clue why?? That sucks (nothing in the documentation)!
modified on Wednesday, August 19, 2009 3:47 AM
-
Well, I think I have narrowed it down to the "GetHashCode" being the culprit! After replacing the "GetHashCode" with my own hash function it seems to work in both x86 and x64 OSs.
For Each c As DataColumn In ds.Tables("mytable").Columns
If Not c.ColumnName = "hashvalue" ThenIf r(c) IsNot DBNull.Value Then RowHash += r(c).**GetHashCode**.ToString End If
Next
' ... compare the "RowHash" with the one stored in the "hashvalue" column ...
This article seem to agree. "... the .NET Object.GetHashCode() method, which unfortunately differs between x86 and x64 systems." Any have any clue why?? That sucks (nothing in the documentation)!
modified on Wednesday, August 19, 2009 3:47 AM
I believe that Microsoft's documentation for GetHashCode specifies that no assumption should be made about the value returned, other than the fact that within a given execution context, if a=b, a.GetHashCode=b.GetHashCode. The release of a class with one version of GetHashCode does not imply a contract that all versions of the class will yield the same GetHashCode; indeed, there may be good reasons why future versions would not. For example, someone might have a class to store shapes, using a fairly simple GetHashCode implementation, and then discover that some particular application which stores shapes in a hash table performs poorly because many different shapes evaluate to the same hash. If the release of the earlier version of GetHashCode compelled all future versions to perform identically on those shapes, it would be impossible to fix its poor behavior with certain combinations of shapes. Allowing GetHashCode to change avoids this risk. Further, I would expect that an object's implementation would even be allowed to have an object's hash code vary based upon the circumstances in which it, or the first still-existing object like it, was created. For example, an object holds a strings could, every time the string is modified, check for it in a dictionary and either use or add a dictionary reference. If all matching strings would use the same dictionary reference, the object's GetHashCode could use the hash of that dictionary reference rather than computing the actual hash of the string, even though the hash of the dictionary reference would be affected by when the object was first inserted.
-
I believe that Microsoft's documentation for GetHashCode specifies that no assumption should be made about the value returned, other than the fact that within a given execution context, if a=b, a.GetHashCode=b.GetHashCode. The release of a class with one version of GetHashCode does not imply a contract that all versions of the class will yield the same GetHashCode; indeed, there may be good reasons why future versions would not. For example, someone might have a class to store shapes, using a fairly simple GetHashCode implementation, and then discover that some particular application which stores shapes in a hash table performs poorly because many different shapes evaluate to the same hash. If the release of the earlier version of GetHashCode compelled all future versions to perform identically on those shapes, it would be impossible to fix its poor behavior with certain combinations of shapes. Allowing GetHashCode to change avoids this risk. Further, I would expect that an object's implementation would even be allowed to have an object's hash code vary based upon the circumstances in which it, or the first still-existing object like it, was created. For example, an object holds a strings could, every time the string is modified, check for it in a dictionary and either use or add a dictionary reference. If all matching strings would use the same dictionary reference, the object's GetHashCode could use the hash of that dictionary reference rather than computing the actual hash of the string, even though the hash of the dictionary reference would be affected by when the object was first inserted.
Thank you for your comment. I agree, between versions (or even builds) an implementation should be allowed to change and also to change its return value. But here we are talking about exactly the same "implementation" (of the method) behaving on differently depending on the platform/CPU (x86 vs x64). As much as your comment makes sense, I can't see how it applies to the same implementation across CPU - am I missing something? PS: The "sucks" was just venting my frustration :sigh: as my newly found wisdom has caused me quite an substantial bit of extra work :doh:
-
Thank you for your comment. I agree, between versions (or even builds) an implementation should be allowed to change and also to change its return value. But here we are talking about exactly the same "implementation" (of the method) behaving on differently depending on the platform/CPU (x86 vs x64). As much as your comment makes sense, I can't see how it applies to the same implementation across CPU - am I missing something? PS: The "sucks" was just venting my frustration :sigh: as my newly found wisdom has caused me quite an substantial bit of extra work :doh:
But here we are talking about exactly the same "implementation" (of the method) behaving on differently depending on the platform/CPU (x86 vs x64). How do you know that it's really the same implementation? I don't know what operations Microsoft's x86 version of .GetHashValue does for different operand types, but if it uses some operations which are efficient on the x86 and less efficient on x64, or fails to use operations which would be more efficient on the x64, would you want Microsoft to use an inefficient version of .GetHashValue for the x64 versions of .net, or should it use efficient ones?
-
But here we are talking about exactly the same "implementation" (of the method) behaving on differently depending on the platform/CPU (x86 vs x64). How do you know that it's really the same implementation? I don't know what operations Microsoft's x86 version of .GetHashValue does for different operand types, but if it uses some operations which are efficient on the x86 and less efficient on x64, or fails to use operations which would be more efficient on the x64, would you want Microsoft to use an inefficient version of .GetHashValue for the x64 versions of .net, or should it use efficient ones?
"would you want Microsoft to use an inefficient version of .GetHashValue for the x64 versions of .net, or should it use efficient ones?" ...it depends on how it affects me :laugh: oh well, for me, a nuisance thats all - thanks for enlightening me! :thumbsup:
-
Hi All Hopefully someone can help shed some light for me. I have some code I have used for years to calculate and store (in SQL Server database), and retrieve and compare a hash value using ComputeHash of the MD5CryptoServiceProvider. I have recently upgraded to x64 (Windows 7) from x86 (Vista) but now my hashes calculated on the x86 does not match when compared (using x64)! (Hope that all makes sense.) Is there any obvious reasons for this? Where should I be looking?? thanx
francoisdotnet wrote:
Where should I be looking??
You should be looking in the documentation[^] which makes it very clear that hash values are not fixed from one environment to the next, and cannot be shared between systems. Their sole purpose is to speed up things on one machine by providing a reasonable hash value as fast as possible. :)
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get. Show formatted code inside PRE tags, and give clear symptoms when describing a problem.