匹配具有不同文件名的两个相同图像

Dav*_*ter 3 c# image

如果一个图像用两个不同的文件名保存了两次,有没有办法比较它们以查看它们是否相同..?

我希望基本的哈希或CRC类型检查可以工作..?

文件大小可能不会,因为池中有数百万个图像,不同的图像可能具有相同的大小.

希望有一个简单的方法在C#中做到这一点..

Jon*_*eet 7

如果文件内容相同,那么加密哈希至少会给出相同的非常好的指示.这个SHA256班级在这里是一个很好的候选人,虽然它可能有点超过顶部.例如:

static byte[] Sha256HashFile(string file)
{
    using (SHA256 sha256 = SHA256.Create())
    {
        using (Stream input = File.OpenRead(file))
        {
            return sha256.ComputeHash(input);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

比较两个返回的字节数组的最简单方法可能是使用它们将它们转换为字符串Convert.ToBase64,然后比较字符串.丑陋但容易:)你也可以使用Enumerable.SequenceEqual:

byte[] hash1 = Sha256HashFile("file1.png");
byte[] hash2 = Sha256HashFile("file2.png");
bool same = hash1.SequenceEqual(hash2);    
Run Code Online (Sandbox Code Playgroud)

如果你想将哈希存储为一个集合或字典,你可以实现自己的,IEqualityComparer<byte[]>但坦率地说,使用base64字符串是最容易的.例如,这将打印出重复的文件:

var hashToNameMap = new Dictionary<string, string>();
foreach (string file in files)
{
    byte[] hash = Sha256HashFile(file);
    string base64 = Convert.ToBase64(hash);
    string existingName;
    if (hashToNameMap.TryGetValue(base64, out existingName))
    {
        Console.WriteLine("{0} is a duplicate of {1}", file, existingName);
    }
    else
    {
        hashToNameMap[base64] = file;
    }
}
Run Code Online (Sandbox Code Playgroud)

几点说明:

  • 这不能保证准确,但是发生碰撞的可能性非常小,特别是如果文件也必须是有效图像.
  • 这包括读取所有每一个文件-即使有与同尺寸没有其他文件(因此没有可能重复).这对您来说可能是也可能不是问题.
  • 即使相同大小的文件,你只需要阅读所有的人都找到重复的...你可能读取的文件和你去计算哈希值,一旦你发现的文件是不同的停止.

你如何处理这取决于你的目标是绝对速度,代码的简单性等.它还可能取决于池是否会随着时间的推移而增长 - 例如,你可能希望在获得两个或更多文件时立即散列文件同样大小的,所以,当你添加同样大小的另一个文件,你可以哈希,添加它而不用重新读取现有的数据.