将字符串转换为 64 位整数






4.16/5 (11投票s)
一个 C# 库的通用函数,可以将字符串转换为类似于 `object.GetHashCode()` 的唯一 64 位整数。
引言
.NET Framework 提供了 'GetHashcode()
' 函数,返回一个 32 位整数。您可以将 'string
' 转换为 32 位整数,但它不能保证数字的唯一性。以下函数将 string
转换为唯一的 64 位整数,避免了存储、比较和跟踪 string
时发生冲突。
背景
如果您需要在数据库中存储大量的 URL,则必须定义 '字符' 索引以进行操作。如果您能够生成匹配的 '一个字符串对应一个数值',则可以用作数值 '键',而不是可变长度的 string
。
Using the Code
- 将可变长度的
string
转换为固定长度的哈希码,并且必须具有快速的哈希速度,因此使用 .NET 提供的System.Security.Cryptography.SHA256CryptoServiceProvider
。 - 将 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 日:初始发布