В C# 4.0, как получить 64-битный хэш-код строки

Я хочу получить 64-битный хэш-код данной строки. Как я могу сделать это с помощью fastest way ? Существует готовый метод для получения 32-битного хэш-кода, но мне нужен 64 бит.

Я ищу только целочисленное хеширование. Не md5.

большое спасибо.

C# 4.0

5 ответов


этот код статья проекта кода-преобразовать строку в 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);
}  

простое решение:

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;
}

я использовал решение @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, мне это было очень полезно!


Я предполагаю, что вы ссылаетесь на алгоритм хеширования 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);

поскольку вопрос был о создании URL, я предполагаю, что вам всегда нужен один и тот же хешированный 64-битный int. GetHashCode не является relyable таким образом. Чтобы сделать хэш с несколькими столкновениями, я использую этот.

public static ulong GetUInt64Hash(HashAlgorithm hasher, string text)
    {
        using (hasher)
        {
            var bytes = hasher.ComputeHash(Encoding.Default.GetBytes(text));
            return Enumerable.Range(0, bytes.Length / 8) //8 bytes in an 64 bit interger
                .Select(i => BitConverter.ToUInt64(bytes, i * 8))
                .Aggregate((x, y) => x ^ y);
        }
    }

использовать его просто передать, что hashalgorithm вы предпочитаете

ulong result = GetUInt64Hash(SHA256.Create(), "foodiloodiloo")

или

ulong result = GetUInt64Hash(MD5.Create(), "foodiloodiloo")

разница между этим и принятым ответом заключается в том, что этот XOR-все биты, и вы можете использовать любой алгоритм, который хотите