.NET Core应用程序每次启动后使用string.GetHashCode()方法获取到的哈希值(hash)不相同
Posted on 2023-07-10 17:24 WebEnh 阅读(143) 评论(0) 编辑 收藏 举报前言
如标题所述,在ASP.NET Core应用程序中,使用string.GetHashCode()
方法去获取字符串的哈希值,但每次重启这个ASP.NET Core应用程序之后,同样的字符串的哈希值(hash)但不相同了。这是什么意思呢?
具体的应用场景是这样的: 项目中有一张表的某个字段保存了类似URL这样的字符串,这张表的数据量比较大,而且这个字段会被经常用作检索。所以,为了提高查询效率,在存储的时候同时存储了这个URL字段的哈希值(hash)。
原来ASP.NET MVC 5项目的.NET Framework版本中,随便应用程序怎么重启,使用string.GetHashCode()
方法获取到的哈希值永远都是一致的(也需要保持一致)。
但在ASP.NET Core 应用程序中,使用string.GetHashCode()
方法,就出现了上述的问题,导致程序在相应的功能部分也出现Bug。最终经过多次测试和查阅资料,定位到了问题的原因。
问题重现
这里我重现一下问题的场景,以下是.NET Framework 4.6.1版本的string.GetHashCode()
方法在不断重启程序之后获取到的哈希值(hash),每次获取到的都是相同的值:
using System; namespace ConsoleApp2 { class Program { static void Main() { var str = "Hello world"; Console.WriteLine(str.GetHashCode()); Console.ReadKey(); } } }
输出:-1660742776
但是,如果在.NET Core应用程序中执行以上相同的代码,每次重启程序后获取到的哈希值是不相同的。
比如我重启测试了三次.NET Core应用程序,分别得到了三个不同的哈希值:313140527
, -1169381487
, 2141605647
。
在定位到问题之后,我们得找出生成不同哈希值的原因。经过一番努力查找之后,其实微软官方文档给出过使用GetHashCode()
方法的建议(文档地址)。其中也明确提示了,不应该将使用.NET内置的GetHashCode()
方法获取到的值作为持久化的值。
Hash codes are used to insert and retrieve keyed objects from hash tables efficiently. However, hash codes don’t uniquely identify strings. Identical strings have equal hash codes, but the common language runtime can also assign the same hash code to different strings. In addition, hash codes can vary by version of .NET, by platform within a single version, and by application domain. Because of this, you should not serialize or persist hash code values, nor should you use them as keys in a hash table or dictionary.
如何获取一个恒定的哈希值(hash)
那要确保.NET Framework和.NET Core应用程序获取到的哈希值都是相同的,我们需要自定义实现哈希值的算法,以下列出一个可行的算法:
public static class HashHelper { public static int GetDeterministicHashCode(this string str) { unchecked { int hash1 = (5381 << 16) + 5381; int hash2 = hash1; for (int i = 0; i < str.Length; i += 2) { hash1 = ((hash1 << 5) + hash1) ^ str[i]; if (i == str.Length - 1) break; hash2 = ((hash2 << 5) + hash2) ^ str[i + 1]; } return hash1 + (hash2 * 1566083941); } } }
完整调用示例(.NET Core):
using System; namespace ConsoleApp1 { class Program { static void Main(string[] args) { var str = "Hello world"; Console.WriteLine(str.GetDeterministicHashCode()); Console.WriteLine(str.GetDeterministicHashCode()); Console.WriteLine(str.GetDeterministicHashCode()); Console.WriteLine("****************************"); Console.WriteLine(str.GetHashCode()); Console.WriteLine(str.GetHashCode()); Console.WriteLine(str.GetHashCode()); Console.ReadKey(); } } public static class HashHelper { public static int GetDeterministicHashCode(this string str) { unchecked { int hash1 = (5381 << 16) + 5381; int hash2 = hash1; for (int i = 0; i < str.Length; i += 2) { hash1 = ((hash1 << 5) + hash1) ^ str[i]; if (i == str.Length - 1) break; hash2 = ((hash2 << 5) + hash2) ^ str[i + 1]; } return hash1 + (hash2 * 1566083941); } } } }
本博客Android APP 下载 |
![]() |
支持我们就给我们点打赏 |
![]() |
支付宝打赏 支付宝扫一扫二维码 |
![]() |
微信打赏 微信扫一扫二维码 |
![]() |
如果想下次快速找到我,记得点下面的关注哦!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2020-07-10 跨域问题服务端解决办法 Request header field Authorization is not allowed by Access-Control-Allow-Headers
2018-07-10 .net OADate 转javascript的Datetime js 5位 日期 转换
2017-07-10 (转载)开发人员必须用到的开发软件破解
2017-07-10 HTML5漫谈(7)——如何保护HTML5应用代码
2017-07-10 【转】使用Jasob混淆javascript代码
2016-07-10 SQL 查询数据库中所有表信息