views:

61

answers:

3

In my application I need to compute a hash of a given .NET assembly and of a given type. Assemblies and types to hash are loaded dynamically in this scenario.

Object's built-in method GetHashCode returns different value each time an application is started.

How to compute a deterministic hash function of an assembly or a type?

Any assistance would be greatly appreciated.

+1  A: 

That depends on what kind of equality you're looking for, really:

  • If you had another copy of the assembly at a different location, should that change the hash?
  • If the same code was rebuilt, should that change the hash?
  • If the code changed and then was rebuilt, should that change the hash?

You may find that just hashing the full name of the assembly (or type) is enough... but we'd need to know more about your requirements to say for sure.

EDIT: To reply to your comment (originally in a comment, but then it was getting too long):

Okay, that's somewhat tricky... an assembly file contains some things which change on each build (possibly a build date, possibly a random GUID; it's a while since I've investigated). You'll want to throw that data away.

If you're only interested in signatures for the assembly too, you could iterate over all the public types (in lexicographic order), then get the hash of those types and combine them. For each hash, you would get all public members (possibly protected ones too?) and hash the signatures - e.g. by combining the hash of the full names of the return type, member name, and parameters. For each parameter you'd want to include the type, possibly the name, and the ref/out status of it. As you can see, it gets quite complicated :)

To combine multiple hashes (as this is clearly going to involve somewhere :) I tend to use something like this:

int hash = 17;
hash = hash * 31 + FirstHash();
hash = hash * 31 + SecondHash();
hash = hash * 31 + ThirdHash();
// etc
return hash;
Jon Skeet
1. Exact copy of the assembly at a different location should have the same hash as the original assembly.2. If the same code was rebuilt I want hash to stay unchanged.3. Yes, it the code was changed and then rebuilt I want the hash to be different, at least in the case of assembly. With the type's hash I can accept that changing only method's body (and leaving all signatures unchanged) will not change the hash.
mgamer
@michael: I've edited my answer to reflect your comment.
Jon Skeet
A: 

Sorry for an offhand answer!

Amy
-1: It often helps to read the question.
Lasse V. Karlsen
@Amy, I recommend that you delete your answer. It will clean up the page and you won't receive any more down-votes on it.And welcome to Stack Overflow!
Greg
A: 

Consider calling GetHashCode() on the assembly name or on the type's assembly-qualified name. That should be more consistent between executions of your application.

kbrimington