【问题标题】:In .net C# does a hashcode remain same for same value always? [duplicate]在 .net C# 中,对于相同的值,哈希码是否始终保持相同? [复制]
【发布时间】:2021-12-26 22:04:53
【问题描述】:

假设我有一个具有 Name 和 Type 属性的类,如果我将下面的哈希码存储在数据库中,我可以在另一个具有相同名称和类型的进程中比较这个哈希码吗?

哈希码是否相同?

Name.ToLower().GetHashCode() + Type.ToLower().GetHashCode();

【问题讨论】:

  • 只存储实际值有什么问题?
  • 不,绝对不能保证。永远不要那样做。 Read the "Warning" box in the documentation. 最上面的就是Do not serialize hash code values or store them in databases.
  • 不存储GetHashCode 返回的哈希码。底层实现可能会随着时间而改变。在进程的生命周期中,它必须为相同的值返回相同的哈希码,否则字典会损坏(例如)。但是在进程生命周期之间,运行时(或库)的升级可能会改变算法并导致不同的哈希码,而您的数据库中的内容将不匹配。
  • design was demanding this ← 这是什么意思?那是一个人吗? 确切的要求是什么?也许是使用哈希码但不一定是GetHashCode()?在这种情况下,您可以使用许多不同的哈希实现。
  • 在 .NET Core 3.1、.NET 5 和 .NET 6 中,两次运行相同的程序,像 Console.WriteLine("Test".GetHashCode()); 这样简单的东西会产生不同的输出。

标签: c# .net hashcode


【解决方案1】:

不,他们不会,但请在此处寻找更持久的解决方案,以满足您的需求。

首先,the documentation 中有警告:

警告
哈希码用于在基于哈希表的集合中进行高效插入和查找。哈希码不是永久值。出于这个原因:

  • 不要序列化哈希码值或将它们存储在数据库中。
  • 请勿使用哈希码作为键从键控集合中检索对象。
  • 不要跨应用程序域或进程发送哈希码。在某些情况下,可能会基于每个进程或每个应用程序域计算哈希码。
    ...

警告中还有更多内容,但最后一个说明了一个很好的观点。

用这段代码简单地创建一个小程序:

Console.WriteLine("Test".GetHashCode());

然后为 .NET Core 3.1、.NET 5 或 .NET 6 重复运行此命令。

你会得到不同的值

所以要回答你的问题,不,它们不会保持不变

不过,您可以推出自己的实现。这是一个相当简单的字符串哈希码函数实现,只有你自己改变它才会改变:

public static int SemiStableHashCode(string input)
{
    unchecked
    {
        byte[] bytes = Encoding.UTF8.GetBytes(input.Normalize(NormalizationForm.FormKD));
        int result = 17;
        foreach (byte b in bytes)
            result = result * 23 + b;
        return result;
    }
}

话虽如此,我突然想到 .NET 5 和 6 更改了它们的 Unicode 支持以使用 ICU 而不是 Win32,所以谁知道我的方法有多“稳定”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多