hashCode用于什么?它有独特之处吗?

问题描述 投票:108回答:5

我注意到在WP7中的每个控件中都有一个getHashCode()方法,它返回一个数字序列。我可以使用此哈希码来识别项目吗?例如,我想识别设备中的图片或歌曲,并将其检查到哪里。如果为特定项目提供的哈希码是唯一的,则可以这样做。

你能帮我解释一下hashCode和getHashCode()用于什么?

c# hashcode
5个回答
98
投票

MSDN says

哈希码是一个数值,用于在相等测试期间标识对象。它还可以充当集合中对象的索引。

GetHashCode方法适用于散列算法和数据结构,例如散列表。

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

GetHashCode方法可以被派生类型覆盖。值类型必须覆盖此方法,以提供适合该类型的哈希函数,并在哈希表中提供有用的分布。为了唯一性,哈希码必须基于实例字段或属性的值,而不是静态字段或属性。

用作Hashtable对象中的键的对象还必须覆盖GetHashCode方法,因为这些对象必须生成自己的哈希代码。如果用作键的对象不提供GetHashCode的有用实现,则可以在构造Hashtable对象时指定哈希代码提供程序。在.NET Framework 2.0版之前,哈希代码提供程序基于System.Collections.IHashCodeProvider接口。从2.0版开始,哈希代码提供程序基于System.Collections.IEqualityComparer接口。

基本上,存在哈希码以使哈希表成为可能。 保证两个相等的对象具有相同的哈希码。 两个不相等的对象不能保证具有不相等的哈希码(称为冲突)。


191
投票

在了解了它的全部内容之后,我想通过类比写出一个希望更简单的解释:

想想Hashcode就像我们试图独特地识别某人一样

我是一名侦探,正在寻找一名罪犯。让我们称他为克鲁尔先生。 (当我还是个孩子的时候,他是一个臭名昭着的凶手 - 他闯进了一所被绑架的房子,谋杀了一个可怜的女孩,甩了她的身体,而且他还在外面 - 但这是一个单独的事情)。克鲁尔先生有一些特殊的特征,我可以用来在人群中独一无二地识别他。我们在澳大利亚有2500万人。其中一位是克鲁尔先生。我们怎么能找到他?

识别克鲁尔先生的坏方法

显然克鲁尔先生有蓝眼睛。这没有多大帮助,因为澳大利亚近一半的人口也有蓝眼睛。

识别克鲁尔先生的好方法

我还能用什么?我知道:我会用指纹!

好处:

  • 两个人真的很难拥有相同的指纹(不是不可能,但极不可能)。
  • 克鲁尔先生的指纹永远不会改变。
  • 克鲁尔先生整个人的每一个部分:他的外表,头发的颜色,个性,饮食习惯等必须(理想情况下)反映在他的指纹中,这样如果他有一个兄弟(非常相似但不一样) - 那么两者都是应该有不同的指纹。我说“应该”,因为我们无法100%保证这个世界上的两个人会有不同的指纹。
  • 但我们总能保证克鲁尔先生总会拥有相同的指纹 - 并且他的指纹永远不会改变。

上述特征通常产生良好的散列函数。

那么“碰撞”的处理是什么?

所以想象一下,如果我找到了领导者,我会找到一个与克鲁尔先生的指纹相匹配的人。这是否意味着我找到了克鲁尔先生?

........也许!我必须仔细看看。如果我使用SHA256(散列功能)而且我正在一个只有5个人的小镇看 - 那么我很有可能找到他!但是如果我使用MD5(另一个着名的散列函数)并在一个拥有+ 2 ^ 1000人的城镇中检查指纹,那么两个完全不同的人可能具有相同的指纹是相当好的可能性。

那么这一切的好处是什么呢?

哈希码的唯一真正好处是,如果你想在哈希表中放置一些东西 - 并且你想要快速找到对象的哈希表 - 这就是哈希代码的用武之地。它们允许你真正在哈希表中找到东西很快。这是一个大规模提高性能的黑客攻击,但准确性很低。

因此,让我们假设我们有一个填充了人的哈希表 - 澳大利亚有2500万嫌犯。克鲁尔先生在那里的某个地方.....我们怎么能很快找到他?我们需要对它们进行整理:寻找潜在的匹配,或者以其他方式宣告潜在的嫌疑人。你不想考虑每个人的独特特征,因为这需要花费太多时间。你会用什么呢?你会使用哈希码!哈希码可以告诉您两个人是否不同。 Joe Bloggs是不是克鲁尔先生。如果印刷品不匹配那么你就知道它绝对不是克鲁尔先生。但是,如果指纹确实匹配,那么取决于你使用的哈希函数,你找到你的男人的机会已经相当不错了。但这不是100%。您可以确定的唯一方法是进一步调查:(i)他/她是否有机会/动机,(ii)证人等等。

当您使用计算机时,如果两个对象具有相同的哈希码值,那么您再次需要进一步调查它们是否真正相等。例如你必须检查对象是否有例如相同的高度,相同的重量等,如果整数相同,或者如果customer_id是匹配的,那么得出它们是否相同的结论。这通常可能通过实现IComparer或IEquality接口来完成。

主要摘要

所以基本上哈希码是指纹。

Digital Fingerprint - Picture attribute to Pixabay - Freely available for use at: https://pixabay.com/en/finger-fingerprint-security-digital-2081169/

  1. 理论上,两个不同的人/物体仍然具有相同的指纹。或者换句话说。如果你有两个相同的指纹.........那么他们不需要来自同一个人/对象。
  2. Buuuuuut,同一个人/对象将始终返回相同的指纹。
  3. 这意味着如果两个对象返回不同的哈希码,那么您就会100%确定这些对象是不同的。

你需要花3分钟时间绕过上面。或许阅读几次直到它有意义。我希望这对某人有所帮助,因为我学到这一切需要很多的悲伤!


11
投票

GetHashCode()用于帮助支持将对象用作哈希表的键。 (类似的东西存在于Java等中)。目标是每个对象返回一个不同的哈希码,但这通常不能绝对保证。尽管两个逻辑上相等的对象返回相同的哈希码是必需的。

典型的哈希表实现以hashCode值开始,获取模数(从而将值约束在一个范围内)并将其用作“桶”数组的索引。


8
投票

它并不是WP7独有的 - 它存在于所有.Net对象上。它有点像你描述的那样,但我不推荐它作为你的应用程序中的唯一标识符,因为它不能保证是唯一的。

Object.GetHashCode Method


4
投票

这是来自这里的msdn文章:

https://blogs.msdn.microsoft.com/tomarcher/2006/05/10/are-hash-codes-unique/

“虽然你会听到人们说哈希码为给定的输入生成一个唯一的值,但事实是,虽然很难完成,但在技术上可行的是找到两个不同的数据输入,这些输入会散列到相同的值。但是,真的确定有关散列算法有效性的因素在于生成的散列码的长度和被散列的数据的复杂性。“

因此,只需使用适合您的数据大小的哈希算法,它将具有唯一的哈希码。

© www.soinside.com 2019 - 2024. All rights reserved.