首页 > 解决方案 > 如果字符串或整数的 getHashCode() 不能保证是唯一的,为什么要使用它?

问题描述

正如我在标题中所写。

如果在您的应用程序中使用 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。

标签: c#linqhashcodeiequalitycomparer

解决方案


我认为让你感到困惑的是你认为哈希码映射到一个值的地址,但它并不完全一样。

把它想象成书架,哈希码映射到书架的地址。如果其中两个具有相同的 HashCode 将被放置在同一个书架中,并且有一个书架的地址,其中有 3 本书,字典只检查书架上的三本书,而不是所有的书。因此,唯一的哈希码越多,字典查找就越快。

当您创建时,IEqualityComparer如果您可以GetHashCode()返回唯一值,则使用它的 Dictionary 或 HashSet 将比有许多重复项时执行得更快。

检查这个例子:

public int GetShashCode(string ojb)
{
     return obj.Length;
}

虽然它比遍历整个字符串要快得多,但它不是很独特(虽然它是有效的)

这个例子也是有效的,但更糟糕的选择:

public int GetShashCode(string ojb)
{
     return (int)obj[0];
}

根据您可以猜到的字符串内容,您可以制作更好的哈希码(例如,您知道这是一个社会安全号码,格式如下:“XXX-XX-XXXX”,每个 X 代表一个数字)将是一个不错的选择:

public int GetShashCode(string ojb)
{
     return int.Parse(obj.Replace("-",""));
}

推荐阅读