Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 32位快速统一哈希函数。使用MD5/SHA1并截断4个字节?_C#_.net - Fatal编程技术网

C# 32位快速统一哈希函数。使用MD5/SHA1并截断4个字节?

C# 32位快速统一哈希函数。使用MD5/SHA1并截断4个字节?,c#,.net,C#,.net,可能重复: 我需要将许多字符串散列到32位(uint) 我可以使用MD5或SHA1并从中获取4个字节吗?还是有更好的选择 不需要安全,也不需要关心是否有裂缝等等。 我只需要快速和统一地散列到32位。MD5和SHA1应一致 但是,我是否可以使用更好(更快)的内置替代方案?如果不是,你会使用哪一种 这里有人问哪一个更好,但没有其他选择,有一个安全问题(我不关心安全): 如果安全性不起作用,则使用加密哈希函数(如MD5或SHA1)生成一个哈希并从中提取4个字节即可。但它们比各种非加密散列函数慢,因为

可能重复:

我需要将许多字符串散列到32位(uint)

我可以使用MD5或SHA1并从中获取4个字节吗?还是有更好的选择

不需要安全,也不需要关心是否有裂缝等等。 我只需要快速和统一地散列到32位。MD5和SHA1应一致

但是,我是否可以使用更好(更快)的内置替代方案?如果不是,你会使用哪一种

这里有人问哪一个更好,但没有其他选择,有一个安全问题(我不关心安全):

如果安全性不起作用,则使用加密哈希函数(如MD5或SHA1)生成一个哈希并从中提取4个字节即可。但它们比各种非加密散列函数慢,因为这些函数主要是为安全而设计的,而不是为了速度

请看一看非加密散列函数,例如或

  • 非加密散列函数Zoo
    • 性能图

编辑:floodyberry.com域现在由域停车服务注册-删除死链接

最简单但很好的字符串算法如下:

int Hash(string s)
{
  int res = 0; 
  for(int i = 0; i < str.Length; i++)
  {
     res += (i * str[i]) % int.MaxValue;
  }
  return res;
}
int散列(字符串s)
{
int res=0;
对于(int i=0;i
显然,这绝对不是一个安全的哈希算法,但它很快(真的很快)返回32位,而且据我所知,是统一的(我已经尝试了许多算法挑战,并取得了很好的结果)


不用于散列密码或任何合理数据。

是否需要加密强度散列?如果你只需要32位,我打赌不会

试试Fowler-Noll-Vo散列。它速度快,具有良好的分布和雪崩效应,通常可用于哈希表、校验和等:

    public static uint To32BitFnv1aHash(this string toHash, 
       bool separateUpperByte = false)
    {
        IEnumerable<byte> bytesToHash;

        if (separateUpperByte)
            bytesToHash = toHash.ToCharArray()
                .Select(c => new[] { (byte)((c - (byte)c) >> 8), (byte)c })
                .SelectMany(c => c);
        else
            bytesToHash = toHash.ToCharArray()
                .Select(Convert.ToByte);

        //this is the actual hash function; very simple
        uint hash = FnvConstants.FnvOffset32;

        foreach (var chunk in bytesToHash)
        {
            hash ^= chunk;
            hash *= FnvConstants.FnvPrime32;
        }

        return hash;
    }

public static class FnvConstants
{
    public static readonly uint FnvPrime32 = 16777619;
    public static readonly ulong FnvPrime64 = 1099511628211;
    public static readonly uint FnvOffset32 = 2166136261;
    public static readonly ulong FnvOffset64 = 14695981039346656037;
}
publicstaticuint到32bitfnv1ahash(这个字符串到hash,
bool separateUpperByte=false)
{
i可由testohash计算;
if(separateUpperByte)
bytesToHash=toHash.ToCharArray()
.选择(c=>new[]{(字节)((c-(字节)c)>>8),(字节)c})
.SelectMany(c=>c);
其他的
bytesToHash=toHash.ToCharArray()
.选择(转换为ToByte);
//这是实际的哈希函数;非常简单
uint hash=FnvConstants.FnvOffset32;
foreach(bytesToHash中的var块)
{
hash^=块;
散列*=FnvConstants.fnprime32;
}
返回散列;
}
公共静态类FnvConstants
{
公共静态只读单元FnvPrime32=16777619;
公共静态只读ulong FnvPrime64=1099511628211;
公共静态只读uint FnvOffset32=2166136261;
公共静态只读ulong FnvOffset64=14695981039346656037;
}

这对于基于每个对象的字符串摘要(自定义ToString()或其他)为GetHashCode创建语义上相等的哈希非常有用。您可以重载此函数以获取任何
IEnumerable
,使其适用于校验和流数据等。如果您需要64位哈希(ulong),只需复制函数并用64位常量替换使用的常量即可。哦,还有一件事;散列(和大多数一样)依赖于未检查的整数溢出;千万不要在“checked”块中运行此散列,否则它几乎肯定会抛出异常。

CRC(或相关)是否适合此用途?还有
的问题。
?.GetHashCode()可以在.Net版本中更改,但我需要值保持不变。此外,我的大多数字符串都不短。String.GetHashCode()的返回值在.NET Framework的32位和64位版本之间也有所不同,因此实际上,除了进程内相等之外,您不应该依赖它;如果您必须持久化哈希或使用由另一个进程或运行时生成的哈希,您应该使用自己的哈希。因此,您是否要将此哈希持久化到比进程更长的时间?此算法具有极差的雪崩特性。一个简单的算法只需求解最大的C(重复字符十进制值)和N(字符串长度),其中
CN(N+1)/2
minLength
,然后增加字符值,最右边的第一个,保持在目标哈希下和可打印字符代码内,直到哈希完全匹配。正如我所说,速度是关键。安全不是问题。这仅适用于使用哈希表快速检索字符串。