【问题标题】:Comparing large lists of hashes比较大的哈希列表
【发布时间】:2014-05-20 22:09:42
【问题描述】:

我有 2 个列表。一个是来自我拥有的计算机(ListA)的文件的 MD5 和 SHA1 哈希列表。另一个是我从 NSRL (ListB) 下载的 MD5 和 SHA1 哈希列表。它是对许多不同应用程序中包含的文件的 MD5 和 SHA1 哈希值的编译。

我正在尝试找到一种快速的方法来比较这些列表。

仅作为性能参考,来自系统的哈希是一个 7.2gb 的文本文件,NSRL 哈希列表约为 20gb。我有一个具有 32gb 内存的系统来执行处理,所以它应该有足够的内存来将两个文件都加载到内存中。

我研究了Except,还考虑从 ListA 中读取每一行并将其与 ListB 进行比较,但必须有比这更好的方法。有什么想法吗?

此外,这是将机器的哈希值与哈希数据库中的已知哈希值进行比较。它在取证中非常普遍(据我了解),所以我愿意接受已经存在的应用程序的建议。

【问题讨论】:

  • 我很想知道这将用于什么
  • 您可以考虑先对列表进行排序。然后使用类似于归并排序的方法进行比较。
  • @Phillippe Leybaert,这是在系统上查找文件时常见的取证做法。获取每个文件的 MD5/SHA1,将其与已知良好文件列表进行比较(或有时将其与已知不良文件列表进行比较),看看有什么突出的。
  • @Sugitime 我知道这是一种常见的取证做法,但我仍然很好奇您的用例是什么。
  • @Phillippe Leybaert,这是一些课堂作业。拍摄系统图像,获取哈希值(我使用了 ftimes),将哈希值与 NSLR db 进行比较。是这个意思吗?

标签: c# .net hash


【解决方案1】:

使用散列是最快的,但您没有足够的内存将所有这些项目加载到散列中。假设 SHA-1 和 MD5 条目的数量平分,ListA 中大约有 5 亿个条目,ListB 中大约有 10 亿个条目。假设每个指针有 8 个字节,这将是至少 80 亿字节。

相反,您应该先使用Radix Trie 仅存储ListB,然后在读取ListA 时执行比较。它的性能不如哈希,但它是一个很好的时空权衡。

【讨论】:

    【解决方案2】:

    使用哈希集。首先将两个列表中的所有项目加载到HashSets。然后我们 IntersectWith 将花费 O(n)。

    可以肯定,您的情况的瓶颈是将数据从文件读取到内存中。在性能方面我会建议将文本文件读入内存然后解析它。

    【讨论】:

      【解决方案3】:
      1. 创建一个可以保存单个哈希项数据的类
      2. 确保它正确实现 GetHashCode 和 Equals。
      3. 创建 2 个您创建的类型的 HashSets,一个用于 ListA,一个用于 ListB。
      4. 将列表中的所有项目加载到哈希集。
      5. 使用SymmetricExceptWith(需要 O(n))获取不在两个列表中的所有哈希值。

      var setA = new HashSet<Item>(LoadListA());
      var setB = new HashSet<Item>(LoadListb());
      setA.SymmetricExceptWith(setB);
      
      if (setA.Count > 0)
      {
          Console.WriteLine("Extra items ןn A or B");
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-12
        • 1970-01-01
        • 2015-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-18
        • 1970-01-01
        相关资源
        最近更新 更多