【问题标题】:C# Create a hash for a byte array or image [duplicate]C#为字节数组或图像创建哈希[重复]
【发布时间】:2010-10-22 11:26:09
【问题描述】:

可能重复:
How do I generate a hashcode from a byte array in c#

在 C# 中,我需要创建图像的 Hash 以确保它在存储中是唯一的。

我可以轻松地将其转换为字节数组,但不确定如何从那里继续。

.NET 框架中是否有任何类可以帮助我,或者是否有人知道一些高效算法来创建这样一个独特的哈希?

【问题讨论】:

    标签: c# .net image hash


    【解决方案1】:

    .NET 中有很多哈希和提供程序可以创建加密哈希 - 这可以满足您的条件,即它们是唯一的(对于大多数目的来说是防冲突的)。它们都非常快,除非你做一万亿次,否则散列绝对不会成为你的应用程序的瓶颈。

    我个人喜欢 SHA1:

    public static string GetHashSHA1(this byte[] data)
    {
        using (var sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider())
        {
            return string.Concat(sha1.ComputeHash(data).Select(x => x.ToString("X2")));
        }
    }
    

    即使人们说一种方法可能比另一种慢,这都是相对而言的。处理图像的程序肯定不会注意到生成哈希和的微秒级过程。

    关于碰撞,对于大多数目的来说,这也是无关紧要的。即使是像 MD5 这样的“过时”方法在大多数情况下仍然非常有用。仅当系统的安全性依赖防止冲突时,才建议不要使用它。

    【讨论】:

    • Rex 我相信你知道这一点,但正如@AdamRobinson 所说,没有哈希(包括 .NET 加密哈希,如 SHA1)可以确保唯一性;只要哈希是多对一映射,即如果可能的哈希码少于可能的输入。
    • @Spike0xff 在软件中当我们说“独特”时,可以理解为“足够独特”。我没有看到任何迹象表明该线程中的任何人对此感到困惑。
    • 我关心的不仅仅是发帖的人,而是所有阅读的人,如果他们感到困惑,我认为你不一定会看到任何迹象。而且我认为您的意思是“我希望它会被理解为”,因为这不是字典中的定义,也不是我的意思或理解的方式。也许你可以引用一个有信誉的来源?
    • @Spike0xff 无论如何,在人类的有生之年,任何软件都绝对不可能偶然发现两个相同的 128 位哈希。所以认为“除非有人破解算法,否则这是独一无二的”真的没问题。
    • @CamiloMartin 即使在你发帖的时候,这已经不是真的了:mscs.dal.ca/~selinger/md5collision
    【解决方案2】:

    Rex M's answer 中关于使用 SHA1 生成哈希的部分很好(MD5 也是一个流行的选项)。 zvolkov 关于不要不断创建新的加密提供商的建议也是一个很好的建议(如果速度比虚拟保证的唯一性更重要,那么使用 CRC 的建议也是如此。

    但是,不要使用 Encoding.UTF8.GetString() 将 byte[] 转换为字符串(当然,除非您从上下文中知道它是有效的 UTF8)。一方面,它将reject invalid surogates。保证始终为您提供来自 byte[] 的有效字符串的方法是 Convert.ToBase64String()

    【讨论】:

    • 谢谢,你说得对。事实上,这就是我一直在做的事情,但我把那个样本从头顶扔了下来,然后做了第一个 byte[]-to-string 我想到的。
    • 感谢乔纳森的提醒,感谢雷克斯的编辑
    【解决方案3】:

    每次需要计算哈希时创建新的 SHA1CryptoServiceProvider 实例一点也不快。使用同一个实例非常快。

    我还是宁愿做许多 CRC 算法中的一种,而不是加密哈希,因为为加密设计的哈希函数对于非常小的哈希大小(32 位)效果不佳,而这正是您想要的 GetHash( ) 覆盖(假设这是你想要的)。

    查看此链接以获取在 C# 中计算 CRC 的一个示例:http://sanity-free.org/134/standard_crc_16_in_csharp.html

    附:您希望散列很小(16 位或 32 位)的原因是您可以快速比较它们(这就是散列的全部意义,记得吗?)。以字符串形式编码的 256 位长值表示散列在性能方面非常疯狂。

    【讨论】:

      【解决方案4】:

      您可以使用任何标准散列算法,但散列在技术上不能保证唯一性。散列被设计为一种相对快速和/或较小的令牌,以便能够查看一个数据是否可能与另一个相同。完全不同的数据集完全有可能产生相同的哈希,尽管能够通过算法产生这些非常困难。

      除此之外,为了检查可能的身份,MD5 相当快。 SHA 更可靠(MD5 已被黑客入侵,因此不应用于安全性),但速度也较慢。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-05
        • 2011-07-16
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-05
        • 1970-01-01
        相关资源
        最近更新 更多