比较具有相同内容的XLSX文件之间的MD5哈希值

时间:2016-11-30 15:41:24

标签: c# excel hash compare md5

我们有一个内部Web应用程序,它接受来自用户的不同格式的文件,以便将大量数据导入我们的系统。

我们实施的最新升级之一是添加一种方法来检测文件是否先前已上传,如果是,则向用户显示警告和重新提交文件的选项,或取消上传

为实现此目的,我们计算上传文件的MD5,并将其与包含先前上载的文件信息的数据库表进行比较,以确定它是否重复。如果MD5上存在匹配项,则会显示警告,否则会在表中插入新文件信息并继续进行文件处理。

以下是用于生成C#哈希的MD5代码:

private static string GetHash(byte[] input)
{
    using (MD5 md5 = MD5.Create())
    {
        byte[] data = md5.ComputeHash(input);

        StringBuilder bob = new StringBuilder();

        for (int i = 0; i < data.Length; i++)
            bob.Append(data[i].ToString("x2").ToUpper());

        return bob.ToString();
    }
}

一切都很好,但有一个例外。

允许用户上传此进程的.xlsx个文件,遗憾的是,此文件类型还会将文件的元数据存储在文件内容中。 (通过将.xlsx文件的扩展名更改为.zip并提取内容[见下文],可以很容易地看到这种情况。)

Excel Metadata

正因为如此,MD5文件的.xlsx哈希值会随着每次后续保存而改变,即使文件内容相同(只需打开并保存文件而不进行修改)元数据并导致不同的MD5哈希值。

在这种情况下,具有相同记录但在不同时间或不同用户创建的文件将滑过重复文件检测并进行处理。

我的问题:有没有办法确定.xlsx文件的内容是否与之前的文件内容匹配存储文件内容?换句话说:有没有办法生成MD5文件的内容.xlsx哈希值?

1 个答案:

答案 0 :(得分:1)

在计算哈希值之前,您可以从文档中删除不应影响哈希值的片段。

这可以通过将Open XML包的所有部分提取到单个XML文档中,删除不需要的节点并计算生成的XML文档的哈希来实现。请注意,您必须重新计算已上载的Excel文件的哈希才能使其生效,因为哈希现在不再基于二进制文件内容。

这是一个简单的示例程序(添加对WindowsBase.dll的引用):

C:\Users\%USERNAME%\AppData\Local\Temp\TFSTemp\