在C#中,我需要创建一个图像的哈希,以确保它在存储中是唯一的。
我可以轻松地将其转换为字节数组,但不确定如何从那里继续。
.NET框架中是否有任何可以帮助我的类,或者是否有人知道某些高效的算法来创建这样一个独特的哈希?
答案 0 :(得分:56)
.NET中有很多hashsum提供程序可以创建加密哈希 - 它可以满足您的条件,即它们是唯一的(大多数用途是防冲突的)。他们都非常快,并且散列绝对不会成为你的应用程序的瓶颈,除非你做了一万亿次。
我个人喜欢SHA1:
string hash;
using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
}
即使人们说一种方法可能比另一种方法慢,但它们都是相对的。处理图像的程序肯定不会注意到生成hashsum的微秒过程。
关于碰撞,在大多数情况下,这也是无关紧要的。即使像MD5这样的“过时”方法在大多数情况下仍然非常有用。仅当系统的安全性依赖防止冲突时,才建议不要使用它。
答案 1 :(得分:15)
关于使用SHA1生成哈希的Rex M's answer部分是一个很好的部分(MD5也是一个流行的选项)。 zvolkov关于不经常创建新的加密提供程序的建议也是一个很好的建议(如果速度比实际保证的唯一性更重要的话,建议使用CRC。
但是,不使用Encoding.UTF8.GetString()将byte []转换为字符串(除非你从上下文中知道它是有效的UTF8)。首先,它将reject invalid surogates。保证始终为byte []提供有效字符串的方法是Convert.ToBase64String()。
答案 2 :(得分:5)
每次需要计算哈希时创建SHA1CryptoServiceProvider的新实例都不是快速的。使用相同的实例非常快。
我仍然宁愿使用众多CRC算法中的一种而不是加密散列,因为为加密设计的散列函数对于非常小的散列大小(32位)不能很好地工作,这是你想要的GetHash(覆盖(假设这是你想要的)。
检查此链接以获取在C#中计算CRC的一个示例:http://sanity-free.org/134/standard_crc_16_in_csharp.html
P.S。你希望你的哈希值小(16或32位)的原因是你可以快速比较它们(这是哈希的重点,还记得吗?)。由编码为字符串的256位长值表示的哈希在性能方面非常疯狂。
答案 3 :(得分:3)
您可以使用任何标准散列算法,但散列在技术上无法保证唯一性。散列被设计为相对快速和/或小的令牌,以便能够看到一条数据是否可能与另一条相同。完全不同的数据集完全可以生成相同的哈希值,但是能够通过算法生成这些哈希值非常困难。
除此之外,为了检查可能的身份,MD5相当快。 SHA更可靠(MD5已被黑客入侵,所以不应该用于安全性),但它也会更慢。