【问题标题】:Why the GetHashCode does not take advantage of SK.exe tool's hashcode algorithm?为什么 GetHashCode 不利用 SK.exe 工具的哈希码算法?
【发布时间】:2012-03-16 06:43:15
【问题描述】:

MSDNsays:

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

但另一方面,当我使用 sn.exe 工具时,它会确保使用唯一的哈希值来创建强名称程序集。如果我没记错的话,程序集的所有内容都会被转换为哈希值。

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

【问题讨论】:

  • 你的意思是sn.exe
  • 这根本没有意义。 int 不能保证唯一性,它太短了。并且加密哈希比您想要的 GetHashCode() 要贵得多。并且GetHashCode() 必须匹配Equals。因此,当您覆盖 Equals 时,无法覆盖它。
  • SK.exe到底是什么?即使您的意思是 Sn.exe 与 GetHashCode 有什么关系?
  • @Bobby:谢谢;我已纠正错字。另一方面,我并没有说两者之间有关系。亨克和汉斯似乎明白我的意思。

标签: c# .net hash gethashcode


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    这是两个完全不同的东西。

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

    当您签署应用程序(文档)时,您最终会得到更大的哈希值(例如 128 或 256 位)。虽然理论上你可能仍然会发生碰撞,但这并没有实际意义。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        不相关。想知道你怎么能把这两者联系起来!!

        仍然要添加更多参数:

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

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

        SN 只是生成一个随机的唯一数字,对实例没有任何逻辑。

        【讨论】:

        • SN just just generates a random unique number, with no logic over an instance 你确定吗?所有加密哈希函数都以一个字节[] 作为输入,可以认为是instance
        猜你喜欢
        • 2015-12-21
        • 2017-03-06
        • 1970-01-01
        • 2019-12-08
        • 2011-03-08
        • 1970-01-01
        • 2014-12-31
        • 2016-10-22
        相关资源
        最近更新 更多