c# - 如果字符串或整数的 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。
解决方案
我认为让你感到困惑的是你认为哈希码映射到一个值的地址,但它并不完全一样。
把它想象成书架,哈希码映射到书架的地址。如果其中两个具有相同的 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("-",""));
}
推荐阅读
- python - 根据用户输入更新 JSON
- c++ - C++/MySQL 连接器 - CDK 错误:字符串转换失败
- orocrm - 来自 bitnami 的 OroCRM 4.1.6 VM 映像 - 在代理后面时,每个页面上 /api/rest/latest/navigationitems/pinbar 上的错误 404 加载
- python - 退出后如何访问在“while True:try/break”循环中生成的局部变量?
- c# - Caliburn.Micro 导航导致 StackOverflowException
- javascript - 反应useState不更新对象数组
- java - 如何获取给定字符串的文件大小?
- flutter - 发布失败(65')退出代码65
- python-3.x - Python 请求在下载二进制文件时工作非常缓慢
- c++ - STL 列表函数,从列表中删除第 N 个元素并将其替换为同一列表 C++ 中的第 M 个元素。必须使用重新链接