我想要获取给定字符串的64位哈希码。有什么最快的方法可以做到这一点吗?
虽然有一个现成的方法可以获取32位哈希码,但我需要64位。
我只需要整数哈希,不需要md5。
非常感谢。
C# 4.0
简单解决方案:
public static long GetHashCodeInt64(string input)
{
var s1 = input.Substring(0, input.Length / 2);
var s2 = input.Substring(input.Length / 2);
var x= ((long)s1.GetHashCode()) << 0x20 | s2.GetHashCode();
return x;
}
值对于 int64 来说太大或太小。
- Tim.Tang既然问题是关于生成URL,我假设您总是需要相同的哈希值为64位整数。使用GetHashCode不可靠。为了生成具有较少冲突的哈希值,我使用以下方法。
public static ulong GetUInt64Hash(HashAlgorithm hasher, string text)
{
using (hasher)
{
var bytes = hasher.ComputeHash(Encoding.Default.GetBytes(text));
Array.Resize(ref bytes, bytes.Length + bytes.Length % 8); //make multiple of 8 if hash is not, for exampel SHA1 creates 20 bytes.
return Enumerable.Range(0, bytes.Length / 8) // create a counter for de number of 8 bytes in the bytearray
.Select(i => BitConverter.ToUInt64(bytes, i * 8)) // combine 8 bytes at a time into a integer
.Aggregate((x, y) =>x ^ y); //xor the bytes together so you end up with a ulong (64-bit int)
}
}
要使用它,只需传递您喜欢的哈希算法即可。
ulong result = GetUInt64Hash(SHA256.Create(), "foodiloodiloo")
//result: 259973318283508806
或者
ulong result = GetUInt64Hash(SHA1.Create(), "foodiloodiloo")
//result: 6574081600879152103
bytes.Length / 8
)无法与某些算法(如 SHA1)一起使用,因为它们会产生不可分割长度的哈希值(例如,SHA1 会产生一个20字节的哈希值)。 - Nick我将介绍一个新的可能答案。xxHash非常快。在这里查看基准测试:
https://cyan4973.github.io/xxHash/
它有一个NuGet包: https://www.nuget.org/packages/System.Data.HashFunction.xxHash
这里的其他答案要么存在问题,无法真正防止冲突,要么只是现有HashAlgorithm实现的包装器。
xxHash不具备加密强度,但似乎更适合您所需的。它的:
此代码来自于Code Project文章 - 将字符串转换为64位整数
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);
}
我使用了@Kirill的解决方法。由于我有点古怪,不喜欢"var"(我猜这是因为我来自c++),所以我做了一个变体:
string s1 = text.Substring(0, text.Length / 2);
string s2 = text.Substring(text.Length / 2);
Byte[] MS4B = BitConverter.GetBytes(s1.GetHashCode());
Byte[] LS4B = BitConverter.GetBytes(s2.GetHashCode());
UInt64 hash = (UInt64)MS4B[0] << 56 | (UInt64)MS4B[1] << 48 |
(UInt64)MS4B[2] << 40 | (UInt64)MS4B[3] << 32 |
(UInt64)LS4B[0] << 24 | (UInt64)LS4B[1] << 16 |
(UInt64)LS4B[2] << 8 | (UInt64)LS4B[3] ;
我对字节的顺序并不确定,这取决于机器(是小端序还是大端序),但是,谁在乎呢?它只是一个数字(哈希值)。非常感谢@Kirill,对我很有帮助!
var
,那么你可能也不喜欢C++的auto
.... - Sebastian我假设你目前使用的是MD5哈希算法?
你可以使用SHA 256来获得两倍的长度...
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256.aspx
提取...
byte[] data = new byte[DATA_SIZE];
byte[] result;
SHA256 shaM = new SHA256Managed();
result = shaM.ComputeHash(data);
1 - e ^ ( -10^7 * (10^7 - 1) / ( 2 * 2^64 ) )
。 - Jonas Elfström