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

标签 c# .net

<分区>

Possible Duplicate:
What is the best 32bit hash function for short strings (tag names)?

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

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

不需要安全性,也不需要关心是否被破解等。 我只需要快速统一地哈希到 32 位。 MD5和SHA1要统一。

但是我可以使用更好(更快)的内置替代方案吗?如果不是,您会使用两者中的哪一个?

这里有人问哪个更好,但不是替代品,而且存在安全问题(我不关心安全问题):
How to Use SHA1 or MD5 in C#?(Which One is Better in Performance and Security for Authentication)

最佳答案

您需要加密强度散列吗?如果您只需要 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;
}

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

关于c# - 32 位快速统一哈希函数。使用 MD5/SHA1 并截掉 4 个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12272296/

相关文章:

C# SVG(使用 device-cmyk() 或 icc-color())到 PDF 转换

c# - Entity Framework 中循环引用的 WCF Datacontract 序列化问题

c# - 将属性从对象复制到另一个的优雅方式

C# .NET x86/x64 哪个项目决定平台?

.net - 批量转换为VBS

c# - EF Code First 中的计算列

c# - 号码分布

c# - 从日期获取年和周

c# - 如何在 .NET Framework 中创建 gRPC 客户端?

.net - 主导航,类(class)开/关。 HGelp 了解这是如何构建的