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

本文关键字:字符串 64位 代码 哈希 何获取 获取 C#4 | 更新日期: 2023-09-27 18:19:56

我想要得到给定字符串的64位哈希代码。我怎样才能用最快的方法做到这一点?有一种现成的方法可以获得32位的哈希代码,但我需要64位。

我只寻找整数哈希。不是md5。

非常感谢。

C#4.0

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

简单的解决方案:

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

由于问题是关于创建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)
    }
}

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

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

ulong result = GetUInt64Hash(SHA1.Create(), "foodiloodiloo")
//result: 6574081600879152103

这一个和公认的答案之间的区别是,这一个对所有比特进行XOR,并且您可以使用任何您想要的算法

此代码来自代码项目文章-将字符串转换为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);
}  

我将介绍一个新的可能答案。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。它们是否真正防止碰撞值得怀疑。只是包装现有的大型且缓慢的HashAlgorithm实现。

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

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

我想您当前使用的是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);

我使用了@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,这对我很有用!