C#4.0如何获取给定字符串的64位哈希码

Mon*_*RPG 9 .net c# string hash 64-bit

我想得到给定字符串的64位哈希码.我怎么能以最快的方式做到这一点?有一个准备好的方法来获取32位哈希码,但我需要64位.

我正在寻找只有整数散列.不是md5.

非常感谢你.

C#4.0

Kir*_*huk 16

简单方案:

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;
}
Run Code Online (Sandbox Code Playgroud)

  • @MonsterMMORPG,此外,如果你存储这些哈希值更喜欢MD5或任何其他哈希实现(例如@Pratik解决方案),因为未来版本的`string`可能使用不同的算法来计算对象的哈希码. (2认同)

Pra*_*tik 7

此代码来自Code Project Article - 将字符串转换为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);
}  
Run Code Online (Sandbox Code Playgroud)

  • 哇这是使用极端的CPU功率.我将它与strText.GetHashCode()方法进行了比较,这慢了376倍. (9认同)
  • 非常缓慢,依赖于endian和怪异.为什么要从SHA-256哈希中读取3个64位整数并对它们进行xor运算?只要读取一个64位整数并使用它就不会获得任何好处. (7认同)

Dan*_*ter 5

由于问题是关于制作 URL,我认为您总是需要相同的散列 64 位 int。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)
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,只需通过您喜欢的任何哈希算法

ulong result = GetUInt64Hash(SHA256.Create(), "foodiloodiloo")
//result: 259973318283508806
Run Code Online (Sandbox Code Playgroud)

或者

ulong result = GetUInt64Hash(SHA1.Create(), "foodiloodiloo")
//result: 6574081600879152103
Run Code Online (Sandbox Code Playgroud)

这个和公认的答案之间的区别在于这个 XOR 的所有位,你可以使用任何你想要的算法


Men*_*ace 5

我将介绍一个新的可能答案。xxHash 非常快。在这里查看基准:

https://cyan4973.github.io/xxHash/

它有一个 NuGet 包: https://www.nuget.org/packages/System.Data.HashFunction.xxHash

或开源: https://github.com/brandondahler/Data.HashFunction/blob/master/src/System.Data.HashFunction.xxHash/xxHash_Implementation.cs

这里的其他答案要么是 1. 对于它们真正的冲突预防有疑问,要么 2. 只是对大型且缓慢的现有 HashAlgorithm 实现的包装。

xxHash 不是加密强度,但它似乎更适合您的需要。它是:

  1. 一路64位,
  2. 基准测试比其他人更快。
  3. 具有良好的分布,可最大限度地避免碰撞。