1

我经营着一个相当大的网站,我的成员每天都会在其中添加数千张图片。显然有很多重复,我只是想知道在上传图像期间是否可以以某种方式生成图像的签名或哈希,以便我可以存储它。每次有人上传图片时,我都会简单地检查这个签名是否已经存在并触发一个错误,说明这个图像已经存在。不确定 asp.net 是否已经存在这种技术,但我知道 tineye.com 已经采用了哪种技术。

如果您认为您可以提供帮助,我将不胜感激您的意见。

克里斯

4

5 回答 5

2

一个可能感兴趣的关键字是感知散列

于 2009-12-02T19:37:53.813 回答
1

您可以使用任何派生的 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());
于 2009-12-02T19:19:05.740 回答
1

查看 System.Security.Cryptography 命名空间。您可以选择几种散列算法/实现。这是一个使用 md5 的示例,但是由于您有很多这些,您可能需要更大的东西,例如 SHA1:

public byte[] HashImage(Stream imageData)
{
    return new MD5CryptoServiceProvider().ComputeHash(imageData);
} 
于 2009-12-02T19:22:00.250 回答
1

通常,您只需使用 MD5 或类似方法来创建哈希。不过,这不能保证是唯一的,所以我建议您使用哈希作为起点。确定图像是否与您存储的任何已知哈希匹配,然后单独加载它匹配的哈希,并对潜在的冲突进行完整的字节比较以确定。

另一种更简单的技术是简单地选择少量的位并读取图像的第一部分......存储该数量的起始位,就好像它们是哈希一样。这仍然会为您提供少量需要检查的潜在冲突,但开销要少得多。

于 2009-12-02T19:24:51.883 回答
0

我不知道它是否已经存在,但我想不出你自己不能这样做的原因。与此类似的内容将为您提供文件的哈希值。

var fileStream = Request.Files[0].InputStream;//the uploaded file
var hasher = System.Security.Cryptography.HMACMD5();
var theHash = hasher.ComputeHash(fileStream);

系统安全密码学

于 2009-12-02T19:20:33.137 回答