C# 4.0 How to get 64 bit hash code of given string

ⅰ亾dé卋堺 提交于 2021-01-26 23:53:16

问题


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:

  1. 64 bits all the way,
  2. Bench-marked faster than others.
  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!