【问题标题】:Why are HashTable order different in Visual Studio Debugging compared to IIS为什么与 IIS 相比,Visual Studio 调试中的 HashTable 顺序不同
【发布时间】:2015-01-16 12:02:47
【问题描述】:

在我的 HashTables 应用程序中发生了一件非常奇怪的事情。

首先:是的,我知道 HashTables 不应该以插入的方式或任何其他方式(但键的哈希值)排序。那没有回答我的问题。我不需要订购它,我只是想知道为什么它在两个看似相同的系统之间有所不同。

所以,就是这样。左边是IIS排序,右边是Visual Studio。

为什么不一样?考虑到 .NET 应该(?)使用相同的算法来存储和检索来自 HashTable 的数据,所以两边的顺序应该是相同的,不是吗?

如果,据我所知,HashTable 的键是散列的,那么这个散列在两个系统上应该是相同的,从而产生相同的散列(键)顺序,因此哈希表中的数据顺序相同。

我哪里错了? IIS和VS的HashTable实现有什么区别?

来自 cmets 的一些额外说明:

  • 项目面向 .NET 4.0
  • IIS 使用 .NET 4.0 作为应用程序池
  • 其实我把编译好的二进制文件从Visual Studios的bin文件夹复制到了IIS文件夹,所以完全一样
  • 我的假设是 IIS 使用与 Visual Studio 相同的 .NET 实现。如果不是:为什么?是什么让 IIS 上的散列与 Visual Studio 中的散列如此不同?

【问题讨论】:

  • “顺序应该相同”取决于实现,因此框架。这还取决于您是否已经删除了项目。
  • 他们最近添加了一个功能来打乱哈希码,这样攻击者就不能轻易地强迫大量的哈希冲突导致 DOS 情况。在 BCL 中搜索名为“MarvinsHashCode”之类的内部方法...
  • @FlorianPeschka 它是 InternalMarvin32HashString 和 UseRandomizedStringHashAlgorithm 配置元素。这就是我所知道的。
  • @FlorianPeschka 我怀疑在非托管代码中获取配置是有原因的。通常,字符串类只能从 app.config 读取配置,但它不能。一定是有原因的。一定有一些更进一步的逻辑,可能取决于 CLR 主机。
  • @FlorianPeschka github.com/floodyberry/Marvin32/blob/master/Marvin32.c 这就是算法。但是,这并不能回答种子的来源以及使用算法的原因。

标签: c# hashtable


【解决方案1】:

为了使表中的项目具有相同的排序,必须满足几个条件:

  1. 哈希算法必须相同。这不仅意味着散列函数,还意味着表增长、收缩、处理冲突等的方式。这可能是您的情况的原因(不同的算法)。
  2. 环境必须相同。如果散列算法的参数之一来自环境,例如可用内存,则有意义。一些算法非常复杂,试图避免页面丢失或出于安全目的对表格进行修饰。
  3. 数据必须相同,并以相同的顺序存储在哈希表中。

【讨论】:

  • 这在理论上回答了它。我希望找到一些确凿的证据来证明 (1) 和 (2) 到底是什么。 (3) 肯定是一样的,我确认了。
  • @Florian,对不起,我以为你问的是“为什么有区别”,而不是“有什么区别”。回答这个问题需要非常具体的知识,甚至可能需要内部知识。
  • “如果哈希算法的参数之一是来自环境的东西,比如可用内存,那么这是有道理的”这不可能是真的。哈希算法是确定性的。
  • @Dialectus 好的,也许我应该在问题中写得更清楚。我知道这可能无法回答,但我也希望在某处记录此效果/问题,无论是否有答案。
  • @Hamlet,“确定性”意味着相同的输入不能产生不同的输出(甚至是不同的内部状态),但环境可以是输入的一部分。
【解决方案2】:

正如@usr 帮助我发现的那样,这种行为的原因在于GetHashCode() 函数,该函数用作HashTables 键的基础。根据键的不同,HashTable 的迭代顺序会有所不同。

散列函数通常应该返回相同的散列或每个输入,但是...此函数返回不同的散列,取决于配置参数,即<UseRandomizedStringHashAlgorithm>,它将返回不同的散列,由一个神秘的函数InternalMarvin32HashString()创建。

引入它是为了防止 Hash Flooding DOS 攻击向量。

不过这个功能

[...] 是从外部 DLL 导入的,准确地说是 clr.dll。

来自Martin Boßlet Dec 14th, 2012

所以我们无法真正知道,如果不进行一些重大(甚至可能是非法的)重构,它究竟做了什么。

【讨论】:

    猜你喜欢
    • 2014-03-13
    • 1970-01-01
    • 2010-09-11
    • 2011-09-03
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    相关资源
    最近更新 更多