【发布时间】:2019-12-07 12:33:48
【问题描述】:
正如我在标题中所写。
如果在您的应用程序中使用 getHashCode() 不安全,为什么要使用它? (对于字符串和整数) 我想用它来交叉方法,除了 Linq 模型中的方法 或创建我自己的 IEqualityCompare 类。 感觉像是一个机会——如果不是 100% 安全?
还是我错过了什么?
正如https://docs.microsoft.com/中的String.GetHashCode方法所引用的那样
重要
如果两个字符串对象相等,则 GetHashCode 方法返回相同的值。但是,每个唯一的字符串值都没有唯一的哈希码值。不同的字符串可以返回相同的哈希码。
不保证哈希码本身是稳定的。对于单个 .NET 版本,相同字符串的哈希码在 .NET 实现、.NET 版本以及 .NET 平台(例如 32 位和 64 位)之间可能会有所不同。在某些情况下,它们甚至可能因应用程序域而异。这意味着同一程序的两次后续运行可能会返回不同的哈希码。
因此,哈希码绝不能在它们所在的应用程序域之外使用 创建时,它们不应该被用作集合中的关键字段,也不应该被持久化。
最后,如果出现以下情况,请不要使用哈希码代替加密哈希函数返回的值 你需要一个加密的强哈希。对于加密哈希,使用从 System.Security.Cryptography.HashAlgorithm 或 System.Security.Cryptography.KeyedHashAlgorithm 类。
有关哈希码的详细信息,请参阅 Object.GetHashCode。
【问题讨论】:
-
来自
GetHashCode的哈希不是安全哈希,但您可能不需要Except和Intersect的安全哈希。 -
我猜关键是“两个后续运行”,我从未观察到同一 AppDomain 中的两个 string.GetHashCode 调用都返回了两个不同的 HashCode。我最近尝试使用 GetHashCode 来评估我的序列化对象图和反序列化对象图是否基于其值 GetHashCode 相同,因为它们与我重新启动应用程序时不同。只有在我的单元测试中,它们与调用序列化和反序列化的过程相同。
-
GetHashCode不是为了安全。唯一的目的是生成索引。您引用的文档明确指出不使用GetHashCode进行安全哈希,而是使用System.Security.Cryptography命名空间中的类。 -
你从不使用 only GetHashCode(),接下来你使用 Equals() 来测试相等性。关键是哈希可以显着减少你必须做的相等测试的数量。 this Q+A 很好地证明了这如何产生代码的主要加速。
-
如果我没记错的话,.net 框架中的底层 GetHashCode 实现是将指针值考虑在内,对于原始值,它在字符串表中的位置(忘记了如何调用表)
标签: c# linq hashcode iequalitycomparer