我运行了一个相当大的网站,我的会员每天都会添加数千张图片。显然有很多重复,我只是想知道在上传图像时我是否可以某种方式生成图像的签名或散列,以便我可以存储它。每当有人上传图片时,我只会检查这个签名是否已经存在并发出错误声明该图片已经存在。不确定这种技术是否已经存在于asp.net但是我知道tineye.com已经有哪种技术了。
如果您认为可以提供帮助,我将非常感谢您的意见。
克里斯
答案 0 :(得分:2)
使用任何派生的HashAlgorithm从文件的字节数组生成哈希。通常使用MD5,但您可以将其替换为System.Security.Cryptography命名空间中提供的任何内容。这适用于任何二进制文件,而不仅仅是图像。
当您下载文件时,许多网站会提供MD5哈希,以验证您是否已正确下载文件。例如,当您收到整个内容时,ISO CD / DVD映像可能会丢失字节。下载完文件后,为其生成哈希,并确保它与网站所说的相同。如果全部进行比较,则表示您已准确复制。
我可能会使用类似的东西:
public static class Helpers
{
//If you're running .NET 2.0 or lower, remove the 'this' keyword from the
//method signature as 2.0 doesn't support extension methods.
static string GetHashString(this byte[] bytes, HashAlgorithm cryptoProvider)
{
byte[] hash = cryptoProvider.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
}
需要:
using System.Security.Cryptography;
使用以下方式致电:
byte[] bytes = File.ReadAllBytes("FilePath");
string filehash = bytes.GetHashString(new MD5CryptoServiceProvider());
或者如果您在.NET 2.0或更低版本中运行:
string filehash = Helpers.GetHashString(File.ReadAllBytes("FilePath"), new MD5CryptoServiceProvider());
如果您决定使用不同的哈希方法而不是MD5来获得极小的碰撞概率:
string filehash = bytes.GetHashString(new SHA1CryptoServiceProvider());
这样你的has方法不是加密提供者特定的,如果你决定要改变你正在使用的加密提供者,你只需要在cryptoProvider参数中注入另一个加密提供者。
您只需更改传入的服务提供商即可使用任何其他哈希类:
string md5Hash = bytes.GetHashString(new MD5CryptoServiceProvider());
string sha1Hash = bytes.GetHashString(new SHA1CryptoServiceProvider());
string sha256Hash = bytes.GetHashString(new SHA256CryptoServiceProvider());
string sha384Hash = bytes.GetHashString(new SHA384CryptoServiceProvider());
string sha512Hash = bytes.GetHashString(new SHA512CryptoServiceProvider());
答案 1 :(得分:1)
查看System.Security.Cryptography命名空间。您可以选择几种散列算法/实现。这是一个使用md5的例子,但由于你有很多这些你可能想要更大的东西,如SHA1:
public byte[] HashImage(Stream imageData)
{
return new MD5CryptoServiceProvider().ComputeHash(imageData);
}
答案 2 :(得分:1)
通常,您只需使用MD5或类似方法来创建哈希。这不保证是唯一的,所以我建议你使用哈希作为起点。确定图像是否与您存储的任何已知哈希值匹配,然后单独加载它匹配的哈希值,并对可能发生的冲突进行完整的字节比较。
另一种更简单的技术是简单地选择少量的位并读取图像的第一部分...将这些起始位存储起来就好像它们是一个哈希一样。这仍然会为您提供您需要检查的少量潜在冲突,但开销要少得多。
答案 3 :(得分:0)
我不知道它是否已经存在,但我想不出你自己不能这样做的原因。类似的东西会让你得到一个文件的哈希值。
var fileStream = Request.Files[0].InputStream;//the uploaded file
var hasher = System.Security.Cryptography.HMACMD5();
var theHash = hasher.ComputeHash(fileStream);
答案 4 :(得分:0)
可能感兴趣的关键字是perceptual hashing。