为什么GetHashCode没有利用SK.exe工具的哈希码算法?

时间:2012-02-26 14:53:44

标签: c# .net hash gethashcode

MSDN says

“GetHashCode方法的默认实现不保证不同对象的唯一返回值。”

但另一方面,当我使用sn.exe工具时,它确保了一个唯一的哈希值来创建一个强命名的程序集。如果我没有指出错误,那么程序集的所有内容都将转换为哈希值。

那么,为什么GetHashCode()的默认实现不使用sn.exe使用的相同算法来为对象创建唯一的哈希值,并期望开发人员实现它?

4 个答案:

答案 0 :(得分:2)

这是完全不同的两件事。

GetHashCode()函数定义返回(仅)32位整数。它应该使用快速算法,并且(不能)保证唯一性。 PC可以快速生成足够的字符串来显示冲突。

当您对应用程序(文档)进行签名时,您将得到更大的散列(如128或256位)。虽然理论上你可能仍然有碰撞,但这没有实际意义。

答案 1 :(得分:2)

没有足够的比特。 GetHashCode()返回其中的32个,因此永远不会有超过40亿个不同的值。生日悖论大大降低了这一点。 sn.exe(而不是sk.exe)生成的强名称使用SHA1哈希。返回160位,允许2 ^ 160个不同的值。

这是一个真正的大数字(1.4E48),通过绝对数量确保唯一性。有点类似于使用128位的Guid。不一样,Guid生成器确保不会发生重复,SHA1没有这样的保证。

GetHashCode的位数有限,因为该方法的主要要求是 fast 。除了为散列集合提供存储桶索引之外,它的用途是快速进行相等测试。 GetHashCode需要比Equals(),给予或接受快一个数量级,以使其有用。这需要削减许多角落,通常,包含引用类型的结构的GetHashCode实现仅返回第一个成员的GetHashCode值。

答案 2 :(得分:1)

程序可以创建的对象数量没有限制,可以调用GetHashCode(),然后放弃。但是,GetHashCode()可以返回4,294,967,296个不同值的限制。如果一个程序恰好调用GetHashCode 4,294,967,297次,那么这些调用中至少有一个必须返回之前已经返回的值。

理论上,系统可以保留一个哈希代码值池,以及被放弃的对象将其哈希码放回池中,以便GetHashCode()可以保证它永远不会返回与任何其他 live 对象相同的值(假设至少有不超过4,294,967,296个活动对象)。另一方面,保留这些信息将是昂贵的,并没有真正提供太多的好处。从实际角度来看,系统在构造对象或第一次调用GetHashCode()时生成任意数字也同样出色。偶尔会发生碰撞,但通常不足以打扰编写良好的代码。

顺便说一下,我有时候认为每个对象都有一个64位的ID是有用的,这个ID可以保证唯一,并且还可以按照创建的顺序对对象进行排序。 64位ID永远不会在任何可预见程序的生命周期内溢出,并且能够在某些缓存或实习场景中分配对象排名可能会有所帮助。例如,如果程序通过从文件读取数据生成一些大型对象,并经常扫描它们以发现差异,则通常可以找到包含相同数据但不同的对象。如果发现两个不同的对象是相同且可互换的,则用较旧的对象替换对较新的对象的引用可以大大加快它们之间的未来比较;如果在彼此之间比较许多匹配对象,则许多对较新对象的引用将被替换为对最旧对象的引用,而不必显式地缓存任何内容。然而,如果没有一些确定“年龄”的方法,这种方法就不会真正起作用,因为没有办法知道应该放弃哪一个参考而不利于另一个。

答案 3 :(得分:0)

无关。不知道你怎么能把这两个联系起来!!

仍然要添加更多参数:

值的“哈希码”不能保证不同值的唯一性。但它确实'保证'给定值/对象的相同哈希码!这意味着:

var hashOne = "SO".GetHashCode();
var hastTwo = "SO".GetHashCode();
Debug.Assert(hashOne==hashTwo); //The assertion would succeed.

SN只是生成一个随机唯一编号,在实例上没有逻辑。