在ASP.NET中为重复检测生成图像签名或哈希的方法?

在ASP.NET中为重复检测生成图像签名或哈希的方法?,asp.net,image,hash,duplicates,digital-signature,Asp.net,Image,Hash,Duplicates,Digital Signature,我经营着一个相当大的网站,我的会员每天在那里添加数千张图片。显然,有很多重复,我只是想知道,在上传图像的过程中,我是否能以某种方式生成图像的签名或散列,以便存储它。每次有人上传图片时,我只需检查这个签名是否已经存在,并发出一个错误,说明这个图片已经存在。不确定asp.net是否已经存在这种技术,但我知道tineye.com已经存在这种技术 如果你认为你能帮忙,我将非常感谢你的意见 Kris您可以使用任何派生的哈希算法从文件的字节数组生成哈希。通常使用MD5,但您可以用它来替代System.Sec

我经营着一个相当大的网站,我的会员每天在那里添加数千张图片。显然,有很多重复,我只是想知道,在上传图像的过程中,我是否能以某种方式生成图像的签名或散列,以便存储它。每次有人上传图片时,我只需检查这个签名是否已经存在,并发出一个错误,说明这个图片已经存在。不确定asp.net是否已经存在这种技术,但我知道tineye.com已经存在这种技术

如果你认为你能帮忙,我将非常感谢你的意见


Kris

您可以使用任何派生的哈希算法从文件的字节数组生成哈希。通常使用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());

您可以使用任何派生的哈希算法从文件的字节数组生成哈希。通常使用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());

我不知道它是否已经存在,但我想不出你为什么不能自己做这件事。类似于此的内容将获得文件的哈希

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

我不知道它是否已经存在,但我想不出你为什么不能自己做这件事。类似于此的内容将获得文件的哈希

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

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

public byte[] HashImage(Stream imageData)
{
    return new MD5CryptoServiceProvider().ComputeHash(imageData);
} 

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

public byte[] HashImage(Stream imageData)
{
    return new MD5CryptoServiceProvider().ComputeHash(imageData);
} 

通常,您只需使用MD5或类似工具来创建散列。但这并不保证是唯一的,所以我建议您使用哈希作为起点。确定图像是否匹配您存储的任何已知哈希,然后分别加载它确实匹配的哈希,并对潜在冲突进行全字节比较以确保


另一种更简单的技术是只需选取少量的位并读取图像的第一部分。。。存储该数量的起始位,就像它们是散列一样。这仍然会为您提供少量需要检查的潜在碰撞,但开销要小得多

通常您只需使用MD5或类似工具来创建散列。但这并不保证是唯一的,所以我建议您使用哈希作为起点。确定图像是否匹配您存储的任何已知哈希,然后分别加载它确实匹配的哈希,并对潜在冲突进行全字节比较以确保

另一个更简单的方法是简单地挑一个小麻木
然后读取图像的第一部分。。。存储该数量的起始位,就像它们是散列一样。这仍然会为您提供少量需要检查的潜在碰撞,但开销要小得多

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

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

图像的数量无关紧要-除非有人故意这样做,否则在MD5中不会发生冲突。图像的数量无关紧要-除非有人故意这样做,否则在MD5中不会发生冲突。@ChristopheD根据我的理解,GUID生成也有类似的冲突,但在实际使用中,发生这种情况的可能性很小,不值得担心。@ChristopheD根据我的理解,GUID生成也有类似的冲突,但在实际使用中,发生这种情况的可能性很小,不值得担心。+1是唯一一个指出散列丢失数据时,它只能用作起点,不能用来确定两个事物是否真正相等的人。@Greg-我从理论上理解这一点,但考虑到在实践中,两个文件在纯科学理论设置之外产生相同MD5散列的可能性,这意味着这一论点没有实际意义。散列可能是一种有损算法,但您不能从散列生成文件。它设计用于测试两个文件是否相同。如果文件相同,则散列值相同;如果文件不同,则散列值不同-因为发生冲突的可能性是十亿分之一,服务器上任何两个不同数据段具有相同散列值的可能性很小。在大多数情况下,散列值都是唯一的,但是生成它们确实需要使用整个二进制文件来生成它。对于大图像或大容量的情况,这会带来很大的开销,这就是为什么我提倡只使用文件的第一部分而不是散列。但如果你这样做,就更需要进行双重检查。+1是唯一一个指出散列丢失数据时,它只能用作起点,而不能用于确定两个事物是否真正相等的人。@Greg-我从理论上理解这一点,但考虑到在实践中,两个文件在纯科学理论设置之外产生相同MD5散列的可能性,这意味着这一论点没有实际意义。散列可能是一种有损算法,但您不能从散列生成文件。它设计用于测试两个文件是否相同。如果文件相同,则散列值相同;如果文件不同,则散列值不同-因为发生冲突的可能性是十亿分之一,服务器上任何两个不同数据段具有相同散列值的可能性很小。在大多数情况下,散列值都是唯一的,但是生成它们确实需要使用整个二进制文件来生成它。对于大图像或大容量的情况,这会带来很大的开销,这就是为什么我提倡只使用文件的第一部分而不是散列。但如果你这样做,就更需要仔细检查。