.NET 程序集和类型的哈希值

发布于 2024-09-12 07:50:11 字数 164 浏览 4 评论 0原文

在我的应用程序中,我需要计算给定 .NET 程序集和给定类型的哈希值。 在此场景中,要动态加载要散列的程序集和类型。

每次启动应用程序时,Object 的内置方法 GetHashCode 返回不同的值。

如何计算程序集或类型的确定性哈希函数?

任何帮助将不胜感激。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

來不及說愛妳 2024-09-19 07:50:11

这实际上取决于您正在寻找什么样的平等:

  • 如果您在不同位置有另一个程序集副本,是否应该更改哈希值?
  • 如果重建相同的代码,是否应该改变哈希值?
  • 如果代码发生更改并且然后被重建,是否应该更改哈希值?

可能发现仅对程序集(或类型)的全名进行哈希处理就足够了......但我们需要更多地了解您的要求才能确定。

编辑:回复您的评论(最初在评论中,但后来变得太长):

好的,这有点棘手......程序集文件包含一些在每次构建时都会更改的内容(可能是构建日期,可能是随机的) GUID;我调查已经有一段时间了)。你会想扔掉这些数据。

如果您也只对程序集的签名感兴趣,则可以迭代所有公共类型(按字典顺序),然​​后获取这些类型的哈希值并将它们组合起来。对于每个散列,您将获得所有公共成员(也可能是受保护的成员?)并对签名进行散列 - 例如,通过组合返回类型、成员名称和参数的全名的散列。对于每个参数,您需要包含其类型(可能是名称)及其引用/输出状态。正如你所看到的,它变得非常复杂:)

要组合多个哈希(因为这显然会涉及到某个地方:)我倾向于使用这样的东西:

int hash = 17;
hash = hash * 31 + FirstHash();
hash = hash * 31 + SecondHash();
hash = hash * 31 + ThirdHash();
// etc
return hash;

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;
山田美奈子 2024-09-19 07:50:11

考虑对程序集名称或类型的程序集限定名称调用 GetHashCode()。这在应用程序的执行之间应该更加一致。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文