我有一个API,其中各种类型都有自定义哈希码。这些哈希码基于获取相关对象的字符串表示的哈希值。使用了各种腌制技术,以便尽可能使Hash代码发生冲突,并且具有等效字符串表示的不同类型的对象具有不同的Hash代码。
显然,由于哈希码基于字符串,因此存在一些冲突(无限字符串与32位整数的有限范围)。我使用基于字符串表示的哈希,因为我需要哈希来保持会话,特别是用于对象的数据库存储。
突然间,今天我的代码开始为Objects生成不同的哈希码,这些哈希码会破坏各种各样的东西。它今天早些时候工作,我没有触及哈希码生成中涉及的任何代码。
我知道.Net文档允许在.Net框架版本之间实现哈希码的更改(以及32位和64位版本之间),但我没有更改框架版本,也没有框架更新最近我记得
任何想法,因为这看起来很奇怪?
修改
生成哈希码如下:
//Compute Hash Code
this._hashcode =
(this._nodetype + this.ToString() + PlainLiteralHashCodeSalt).GetHashCode();
答案 0 :(得分:3)
如果Object.ToString()
没有被覆盖,那么StampedeXV在其评论中建议ToString()
默认返回完全限定名称。
ToString()
,则更改名称空间(或类名称)会更改此值。ToString()
会改变它。_nodeType
修改的方式和位置。PlainLiteralHashCodeSalt
仍然是个谜(我认为它是一个常数字符串)。String.HashCode()
不会改变,因此您至少可以使用Reflector来获取方法的来源并将其包含在您的库中。这是不我通常会推荐的内容,但您不希望将来依赖此内容。毋庸置疑,您应该跟踪所有3个值(_nodeType,this.ToString()和salt string)以检查它们是否未更改。如果您可以恢复到可以使用的旧版本,那么您就在那里。
除此之外,不建议持久化哈希码。如果这与性能相关,请注意由数据库负责处理索引和散列。既然你不能保证它是独一无二的,那么它也不是一个GUID。那么重点是什么呢?
但是因为它已经存在于数据库中,所以现在主要关注的是如何恢复HashCode实现。
答案 1 :(得分:1)
您说您使用此哈希码进行持久化。对于当前的实现,这是一个坏主意,因为您使用ToString()
函数来生成哈希码。此函数的结果与持久性无关,也许开发人员需要为GUI设计或任何原因和忘记更改它,它也用于持久性。
在你的情况下,我会查看ToString()
方法的结果,也许它已经改变了。这可以通过改变文化或将对象移动到另一个命名空间来实现 - 只需看看,也许你找到了理由。