16

我像这样声明了一行 C# 代码

int hashcode = "apple".GetHashCode();

在我的电脑、工作的电脑和朋友的电脑上,结果是 1657858284。在开发服务器上,结果是 1548091822。有没有办法告诉项目始终让 GetHashCode() 产生 1657858284,不管它在哪个服务器上?

更多注释 起初,我注意到版本有所不同... 1657858284 结果来自 .NET 3.5 和 .NET 4.0。1548091822 来自 .NET 2.0。

然后我告诉 Visual Studios 2010 将项目编译为 .net 2.0 项目,但它仍然给了我 1657858284。

4

4 回答 4

24

正如其他人所指出的,这与文档一致。您永远不能依赖 GetHashCode 返回相同的东西。您可以依赖的唯一不变量是,如果对象没有以任何方式改变其相等语义的方式发生突变,它将在同一应用域中的同一对象上返回相同的值。如果不满足任何这些条件——如果两个对象位于不同的应用程序域中,或者对象以改变其相等语义的方式发生突变——那么你无法保证“相同”对象将返回相同的哈希代码。

您唯一应该使用哈希码的就是平衡哈希表。任何其他使用都是“标签外”,风险自负。不要这样做。如果您需要一个跨越任意边界的稳定字符串哈希,请使用行业标准算法,如 SHA256 或其他东西。

如果您对此主题感兴趣,请参阅我关于哈希问题的文章存档以获取更多详细信息:

http://blogs.msdn.com/b/ericlippert/archive/tags/hashing/

于 2011-05-24T18:14:11.693 回答
17

您可能正在使用 2 个不同版本的 .Net。此行为在 MSDN 文章中注明:http:
//msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
来自备注:

GetHashCode 方法的默认实现不保证不同对象的唯一返回值。此外,.NET Framework 不保证 GetHashCode 方法的默认实现,它返回的值在不同版本的 .NET Framework 之间是相同的。因此,此方法的默认实现不得用作散列目的的唯一对象标识符。

于 2011-05-24T18:04:59.740 回答
2

为了让您的自定义类返回稳定的哈希码,您应该重写 GetHashCode() 方法,否则将使用 Object 类的 GetHashCode 方法,我认为这可能会有很大差异。(甚至可能是特定于实例的)。

于 2011-05-24T18:06:36.403 回答
1

如果您需要一个校验和,例如允许您在传输中快速验证数据完整性,只需通过具有适当位数的(加密)哈希运行它,如

- MD5
- SHA256
- SHA1
- fletcher

.NetGetHashCode并不意味着识别任何东西(无论如何,32 位很快就会导致冲突,这就是为什么你不能用它来识别字符串。)

请注意,即使是上述四个也会允许碰撞(但不太快);所以请确保将其用作校验和,而不是标识。

于 2011-06-01T23:37:12.043 回答