C#为字节数组或图像创建哈希值

41

可能重复:
如何在C#中从字节数组生成哈希码

在C#中,我需要创建一个图像的哈希值,以确保它在存储时是唯一的。

我可以很容易地将其转换为字节数组,但不确定该如何继续操作。

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

4个回答

68

.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这样“过时”的方法在大多数情况下仍然非常有用。 只有当您的系统的安全性依赖于防止碰撞时才建议不要使用它。


3
Rex,我相信你已经意识到了这一点,但正如@AdamRobinson所指出的那样,没有哈希(包括.NET加密哈希,如SHA1)可以确保唯一性;只要哈希是一个多对一的映射,也就是说,如果可能的输入比可能的哈希码少,就无法保证唯一性。 - Spike0xff
4
在软件中,当我们说“unique”时,通常指的是“足够独特”。我并没有看到任何迹象表明这个讨论串中有人对此感到困惑。 - Rex M
2
我的关注不仅仅是针对发帖者,而是所有阅读者,我认为你不一定会看到他们是否感到困惑。而且我认为你的意思是“我希望它被理解为”,因为这不是字典中的定义,也不是我所理解的方式。也许你可以引用一个可靠的来源? - Spike0xff
2
@Spike0xff 无论如何,在人类有生之年内,没有任何软件能够偶然找到两个相同的128位哈希值。因此,认为“除非有人破解算法,否则这是唯一的”是完全可以的。 - Camilo Martin
2
@CamiloMartin 即使在你发帖的时候,那也已经不是真的了:http://www.mscs.dal.ca/~selinger/md5collision/ - tstark81
显示剩余3条评论

15
关于使用SHA1生成哈希值的Rex M的回答部分是一个好的选择(MD5也是一种流行的选项)。zvolkov关于不要不断地创建新的加密提供者的建议也是一个好的选择(如果速度比几乎保证唯一性更重要,则使用CRC的建议也是一个好的选择)。
然而,不要使用Encoding.UTF8.GetString()将byte[]转换为字符串(除非您从上下文中知道它是有效的UTF8)。首先,它会拒绝无效的代理。确保总能从byte[]得到一个有效字符串的方法是使用Convert.ToBase64String()

谢谢,你说得很对。事实上,那正是我一直在做的,但我随手写下了那个示例,并使用了我能想到的第一个byte[]转string的方法。 - Rex M
谢谢提醒,Jonathan。感谢编辑,Rex。 - johnc

6
每次需要计算哈希时都创建SHA1CryptoServiceProvider的新实例并不快。使用同一实例相当快。
尽管如此,我仍然更愿意使用许多CRC算法之一,而不是加密哈希,因为针对密码学设计的哈希函数对于非常小的哈希大小(32位)效果不太好(这是您想要的GetHash()覆盖所需的内容)。
请查看此链接以获取在C#中计算CRC的一个示例:http://sanity-free.org/134/standard_crc_16_in_csharp.html P.S. 您希望哈希值很小(16或32位),以便可以快速比较它们(这就是拥有哈希的全部意义,记住吗?)。 将哈希表示为256位长值编码为字符串在性能方面相当疯狂。

4

您可以使用任何标准散列算法,但散列本质上无法保证唯一性。散列旨在成为相对快速和/或小型的标记,以便查看一条数据是否很可能与另一条数据相同。完全不同的数据集也可能产生相同的哈希值,尽管能够通过算法生成这些哈希值非常困难。

总之,在检查可能身份时,MD5相当快。 SHA更可靠(由于MD5已被破解,因此不应用于安全),但速度较慢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接