65.9K
CodeProject 正在变化。 阅读更多。
Home

将字符串转换为 64 位整数

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.16/5 (11投票s)

2009年3月20日

CPOL

1分钟阅读

viewsIcon

88143

一个 C# 库的通用函数,可以将字符串转换为类似于 `object.GetHashCode()` 的唯一 64 位整数。

引言

.NET Framework 提供了 'GetHashcode()' 函数,返回一个 32 位整数。您可以将 'string' 转换为 32 位整数,但它不能保证数字的唯一性。以下函数将 string 转换为唯一的 64 位整数,避免了存储、比较和跟踪 string 时发生冲突。

背景

如果您需要在数据库中存储大量的 URL,则必须定义 '字符' 索引以进行操作。如果您能够生成匹配的 '一个字符串对应一个数值',则可以用作数值 '键',而不是可变长度的 string

Using the Code

  1. 将可变长度的 string 转换为固定长度的哈希码,并且必须具有快速的哈希速度,因此使用 .NET 提供的 System.Security.Cryptography.SHA256CryptoServiceProvider
  2. 将 32 字节的哈希码转换为 8 字节的整数,避免产生冲突。
/// <summary>
/// Return unique Int64 value for input string
/// </summary>
/// <param name="strText"></param>
/// <returns></returns>
static Int64 GetInt64HashCode(string strText)
{
    Int64 hashCode = 0;
    if (!string.IsNullOrEmpty(strText))
    {
        //Unicode Encode Covering all characterset
          byte[] byteContents = Encoding.Unicode.GetBytes(strText);
        System.Security.Cryptography.SHA256 hash = 
		new System.Security.Cryptography.SHA256CryptoServiceProvider();
        byte[] hashText = hash.ComputeHash(byteContents);
        //32Byte hashText separate
        //hashCodeStart = 0~7  8Byte
        //hashCodeMedium = 8~23  8Byte
        //hashCodeEnd = 24~31  8Byte
        //and Fold
        Int64 hashCodeStart = BitConverter.ToInt64(hashText, 0);
        Int64 hashCodeMedium = BitConverter.ToInt64(hashText, 8);
        Int64 hashCodeEnd = BitConverter.ToInt64(hashText, 24);
        hashCode = hashCodeStart ^ hashCodeMedium ^ hashCodeEnd;
    }
    return (hashCode);
}        

冲突和性能测试

测试平台:Core2Duo,Windows 2003 Server SP2,.NET Framework 3.5 SP1

生成 GetInt64HashCode 10,000,000 次

冲突:未发现

生成 100,000 次所花费的时间:830 毫秒

生成 .NET Framework 提供的 object.GetHashCode 10,000,000 次

冲突:发现 4,150 个

生成 100,000 次所花费的时间:35 毫秒

关注点

我知道 Cryptography.SHA256 并不提供完美的冲突避免哈希值,并且将 32 字节压缩到 8 字节可能会增加冲突的可能性,但我认为上述函数显示了足够的性能并避免了冲突。

您的回复将使该函数更高效可靠。

此函数现在正在使用并收集大量的 URL。对于 40,000,000 个唯一的 URL,没有发现冲突。

历史

  • 2009 年 3 月 20 日:初始发布
© . All rights reserved.