MD5检查文件夹中的重复文件?

时间:2014-01-25 07:50:35

标签: c# file hash directory md5

假设我有一个包含五百张图片的文件夹,我想检查重复并删除它们。

这是我现在的代码:

using (var md5 = MD5.Create())
{
    using (var stream = File.OpenRead(filename))
    {
        return md5.ComputeHash(stream);
    }
}

如果我在相应的循环中发现重复的MD5,这是否可行?

2 个答案:

答案 0 :(得分:2)

使用任何编程语言,在任何操作系统上创建哈希以识别相同的文件是可以的。但这很慢,因为即使没有必要,你也会阅读整个文件。

我建议多次通过查找重复项:

  1. 获取所有文件的大小
  2. 对于所有相同大小的文件:获取第一个的哈希值,比如1k字节
  3. 对于所有相同大小的文件和第一个1k的相等哈希值:获取整个文件的哈希值
  4. 存在哈希冲突的风险。使用哈希算法无法避免它。由于MD5使用128位,因此对于两个随机文件,风险为1:(1 <&lt; 128)(大约0.0000000000000000000000000000000000000001)。你每周只用一张彩票就可以连续四次获得国家彩票的累积奖金,这比在一对随机文件上发生哈希碰撞要好得多。

    虽然哈希冲突的可能性稍微提高 ,但如果比较许多文件的哈希值。数学上感兴趣的人和实现哈希容器的人应该查找“生日问题”。当他们没有实施加密算法时,凡人都信任MD5哈希。

答案 1 :(得分:1)

using System;
using System.IO;
using System.Collections.Generic;
internal static class FileComparer
{
    public static void Compare(string directoryPath)
    {           
        if(!Directory.Exists(directoryPath))
        {
            return;
        }
        FileComparer.Compare(new DirectoryInfo(directoryPath));
    }
    private static void Compare(DirectoryInfo info)
    {           
        List<FileInfo> files = new List<FileInfo>(info.EnumerateFiles());
        foreach(FileInfo file in files)
        {
            if(file.Exists)
            {
                byte[] array = File.ReadAllBytes(file.FullName);
                foreach(FileInfo file2 in files)
                {                       
                    int length = array.Length;
                    byte[] array2 = File.ReadAllBytes(file2.FullName);
                    if(array2.Length == length)
                    {
                        bool flag = true;
                        for(int current = 0; current < length; current++)
                        {
                            if(array[current] != array2[current])
                            {
                                flag = false;
                                break;
                            }
                        }
                        if(flag)
                        {
                            file2.Delete();
                        }                       
                    }
                }
            }
        }
    }
}