2

我有一个 API,其中各种类型都有自定义哈希码。这些散列码基于获取相关对象的字符串表示的散列。使用了各种加盐技术,以使哈希码尽可能不发生冲突,并且具有等效字符串表示的不同类型的对象具有不同的哈希码。

显然,由于哈希码是基于字符串的,因此存在一些冲突(无限字符串与 32 位整数的有限范围)。我使用基于字符串表示的散列,因为我需要散列在会话中持续存在,特别是在对象的数据库存储中使用。

今天突然间,我的代码开始为破坏各种事物的对象生成不同的哈希码。它今天早些时候工作,我还没有触及任何涉及哈希码生成的代码。

我知道 .Net 文档允许在 .Net 框架版本之间(以及 32 位和 64 位版本之间)实现哈希码,但我没有更改框架版本,并且最近没有框架更新我记得

任何想法,因为这看起来真的很奇怪?

编辑

哈希码生成如下:

//Compute Hash Code
this._hashcode = 
   (this._nodetype + this.ToString() + PlainLiteralHashCodeSalt).GetHashCode();
4

2 回答 2

3

StampedeXV 在他的评论中建议的是,如果没有被覆盖Object.ToString(),默认情况下将返回完全限定的名称。ToString()

  1. ToString()如果未覆盖,更改命名空间(或类名)将更改此值。
  2. 显然,覆盖ToString()会改变它。
  3. 准确检查修改的方式和位置_nodeType
  4. PlainLiteralHashCodeSalt仍然是一个谜(我认为它是一个恒定的字符串)。
  5. 没有人保证这String.HashCode()不会改变,因此您至少可以使用 Reflector 获取方法的源代码并将其包含在您的库中。这不是我通常会推荐的东西,但是您将来不想依赖它。

不用说,您应该跟踪所有 3 个值(_nodeType、th​​is.ToString() 和 salt string)以检查它们是否没有更改。如果您可以恢复到有效的旧版本,那么您已经成功了一半。

除此之外,不建议保留哈希码。如果这与性能相关,请注意您的数据库负责处理索引和散列。而且由于您不能保证它是唯一的,因此它也不是 GUID。那么有什么意义呢?

但由于它已经在数据库中,您现在主要关心的是如何取回 HashCode 实现。

于 2009-10-14T13:22:33.517 回答
1

你说你使用这个哈希码来持久化。这对您当前的实现来说是个坏主意,因为您使用该ToString()函数来生成哈希码。此函数的结果与持久性无关,并且可能开发人员需要出于 GUI 设计或任何原因对其进行更改而忘记了,它也用于持久性。
在你的情况下,我会看看ToString()方法的结果,也许它改变了。这可以通过改变文化或将对象移动到另一个命名空间来发生 - 看看吧,也许你会找到原因。

于 2009-10-14T12:54:57.200 回答