不区分大小写的哈希字符串(SHA)(Case Insensitive hash (SHA) of a

2019-07-29 06:55发布

我传递一个名字字符串,其值SHA1到数据库中。 的SHA值被用作用于搜索的索引。 实施改完之后,我们必须让搜索名称不区分大小写的要求。 我们确实需要采取一切语言考虑(中国字是一个真正的用例)。

我知道的土耳其测试 。 我怎样才能散列是不区分大小写转换前的我输入的字符串? 理想情况下,我想它是等价的InvariantCultureIgnoreCase 。

换句话说,我该如何使这个功能的情况下的输出不敏感?

private byte[] ComputeHash(string s)
{
     byte[] data = System.Text.Encoding.Unicode.GetBytes(s ?? string.Empty);
     SHA1 sha = new SHA1CryptoServiceProvider();     // returns 160 bit value
     return sha.ComputeHash(data);
}

如果SHA是不可能的,我也许能够使String.GetHashCode ()的工作,但我没有看到一个方法,使这种不区分大小写无论是。

我敢打赌,这是不可能的。 如果它不是,都有些什么变通?

Answer 1:

你可以使用s.ToUpperInvariant()之前生成的哈希值。 只要你做的这两种方法(产生原始哈希,并生成一个散列,以测试对原来的),它会工作。



Answer 2:

这表明与tolower(不变)利用现有的答案是错误的:做ToLower将后比较字符串等于做一个string.Compare(xxxIgnoreCase)。 看到这里接受的答案: 字符串比较- strA.ToLower()== strB.ToLower()或strA.Equals(STRB,StringComparisonType)? 它打破了某些类型的字符。

该解决方案是创建一个每个字符串所谓SORTKEY。 这样的SORTKEY本质上是一个字节数组与等于字节意味着等于串的属性。 (另外,SORTKEYS可以以二进制方式产生的确切顺序相同string.Compare产量。但我们并不需要在这里,财产比较)。

摘要:使用CompareInfo.GetSortKey(串).KeyData获得哈希的字节[]。 ( MSDN上GetSortKey )这适用于所有可能的文化。 这也适用于不区分大小写。

这样对于任何给定的字符串(即使土耳其ⅰ)不区分大小写的散列可以与获得:

var sortKeyBytes = CultureInfo.InvariantCulture.CompareInfo.GetSortKey(anyString,
    CompareOptions.IgnoreCase).KeyData;
int hashCode = HashByteArray(sortKeyBytes); //Need to provide this function.
...

我们不能使用的GetHashCode()字节的[按这种方法没有覆盖] byte[]因此缺省为object.GetHashCode()它使用对象的身份和不值。

您可以使用杂凑函数这个答案 。 这并不好,但它的工作。



Answer 3:

为了使事情不区分大小写,删除的情况下:

s = s.ToLowerInvariant();

如果你不能将其存储到数据库,并使用转换其他字符串匹配等不使用的CurrentCulture:

s = s.ToLower(System.Globalization.CultureInfo.CurrentCulture);

您可以考虑使用其他(非不变)文化所有的时间,但它可能是为未来的代码维护者惊喜(一个通常期望电流或固定区域性的所有字符串操作)。



文章来源: Case Insensitive hash (SHA) of a string
标签: c# search hash