问题
I want to get 64 bit hash code of given string. How can i do that with fastest way ? There is a ready method for get 32 bit hash code but i need 64 bit.
I am looking for only integer hashing. Not md5.
Thank you very much.
C# 4.0
回答1:
This code is from Code Project Article - Convert String to 64bit Integer
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);
}
回答2:
Simple solution:
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;
}
回答3:
Since the question was about making URL I presume you always need the same hashed 64 bit int. GetHashCode is not relyable in this way. To make a hash with few collisions i use this one.
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)
}
}
To use it just pass whatever hashalgorithm you prefer
ulong result = GetUInt64Hash(SHA256.Create(), "foodiloodiloo")
//result: 259973318283508806
or
ulong result = GetUInt64Hash(SHA1.Create(), "foodiloodiloo")
//result: 6574081600879152103
Difference between this one and the accepted answer is that this one XOR's all the bits, and you can use whatever algorithm you want
回答4:
I assume you are refering to the MD5 hashing algorithm for your current use?
You can do a SHA 256 for twice the length....
http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256.aspx
Extract...
byte[] data = new byte[DATA_SIZE];
byte[] result;
SHA256 shaM = new SHA256Managed();
result = shaM.ComputeHash(data);
回答5:
I have used the @Kirill solution. I'm a little bit weird and I don't like "var" (I guess it's because I come from c++) so I make a variant:
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] ;
I'm not very sure about the order of the bytes, depends on the machine, (whether is little-endian or big-endian) but, who cares? it's just a number (a hash). Thank you @Kirill, it was very useful to me!
回答6:
I'll introduce a new possible answer. xxHash is very fast. Check out the benchmarks here:
https://cyan4973.github.io/xxHash/
It has a NuGet package: https://www.nuget.org/packages/System.Data.HashFunction.xxHash
Or open sources: https://github.com/brandondahler/Data.HashFunction/blob/master/src/System.Data.HashFunction.xxHash/xxHash_Implementation.cs
The other answers here are either 1. questionable as to their real prevention of collision or 2. just wrappers around the large and slow existing HashAlgorithm implementations.
xxHash is not cryptographic strength, but it would seem to fit the bill better for what you need. Its:
- 64 bits all the way,
- Bench-marked faster than others.
- Has good distribution for maximized collision avoidance.
来源:https://stackoverflow.com/questions/8820399/c-sharp-4-0-how-to-get-64-bit-hash-code-of-given-string