一尘不染

如何在.net(c#)中为安全存储在数据库中的字符串创建HashCode?

c#

引用 埃里克·利珀特(Eric
Lippert)引用的GetHashCode准则和规则

规则: GetHashCode的使用者不能依赖它随时间推移或跨应用程序域的稳定性

假设您有一个Customer对象,该对象具有一堆字段,例如Name,Address等。如果在两个不同的过程中使用完全相同的数据制作两个这样的对象,则它们不必返回相同的哈希码。如果您在一个星期二通过一个进程创建了这样的对象,将其关闭,然后在星期三再次运行该程序,则哈希码可能会有所不同。

过去这已经伤了人们。System.String.GetHashCode的文档特别指出,两个相同的字符串在不同版本的CLR中可以具有不同的哈希码,实际上,它们确实可以。
不要将字符串哈希存储在数据库中,并希望它们永远一样,因为它们不会一样。

那么,创建可以存储在数据库中的字符串的HashCode的正确方法是什么?

(请告诉我,我不是第一个在我编写的软件中留下此错误的人!)


阅读 285

收藏
2020-05-19

共1个答案

一尘不染

这取决于您希望散列具有什么属性。例如,您 可以 编写如下内容:

public int HashString(string text)
{
    // TODO: Determine nullity policy.

    unchecked
    {
        int hash = 23;
        foreach (char c in text)
        {
            hash = hash * 31 + c;
        }
        return hash;
    }
}

只要您 证明
那是哈希的计算方式,那是有效的。它绝对不是加密安全或类似的东西,但是您可以毫无问题地坚持下去。在序数意义上绝对相等的两个字符串(即未应用文化平等等,一个字符一个字符地相同)将使用此代码产生相同的哈希。

当您依赖于 未记录的
散列时,问题就来了,即,遵守GetHashCode()但绝对不能保证版本之间保持不变的某些事物string.GetHashCode()

像这样编写和记录自己的哈希值有点像说:“此敏感信息已用MD5(或其他任何东西)进行哈希处理”。只要是定义明确的哈希,就可以了。

编辑:其他答案建议使用加密散列,例如SHA-1或MD5。我要说的是,除非我们知道对密码安全性的要求而不是对稳定性的要求,否则要经历将字符串转换为字节数组并对其进行哈希处理的繁琐过程是没有意义的。当然,如果哈希
指用于任何与安全有关的,行业标准的哈希 正是 你应该达到什么样的。但这并没有在问题中提到。

2020-05-19