|
|
1
20
2. ),我想)。我会尝试找到一个简单的哈希值来识别可能的候选者进行比较。这在概念上与spdenne和Eduard的建议相似。也就是说,找到一个可以应用于每个项目一次的哈希值,对列表进行排序,然后对列表中哈希值接近的项目进行更细粒度的比较。 LSHKit 软件库实现了这类算法 FINDING SIMILAR FILES IN A LARGE FILE SYSTEM Multi-resolution similarity hashing 描述了一种更强大的算法。不过,如果没有订阅,它似乎无法访问。你可能想保留维基百科上的文章 Locality Sensitive Hashing 方便您浏览其他资源。它们都非常技术化,维基百科条目本身也非常数学化。作为一种更用户友好的替代方案,您可能能够应用以下领域的一些想法(甚至是可执行文件) Acoustic Fingerprinting . 如果你愿意放弃一般情况,你很可能会找到一个更简单(更快)的特定于域的哈希函数,只适用于你的ROM。可能涉及标准或通用字节序列的放置以及它们附近的选择位的值。我对你的二进制格式了解不多,但我在想象一些信号,比如声音、图像或文本的区域,来表示文件中各部分的开始。二进制格式经常将这类部分的地址存储在文件开头附近。有些还使用链式机制,将第一部分的地址及其大小存储在已知位置。这允许您移动到下一节,该节还包含尺寸等。如果你还没有意识到,一点调查可能会让你发现任何相关的格式,并且应该让你很好地构建一个有用的哈希。 如果哈希函数不能完全满足你的需求(或者它们需要某种输入来定义度量/距离),那么网络上有几种二进制增量算法和实现。我最熟悉的是subversion版本控制系统。它使用一种名为xdelta的二进制增量算法来有效地存储二进制文件修订版。以下是直接指向其存储库中实现该文件的链接: xdelta.c 。网络上可能也有一个工具可以让这更容易访问。 |
|
|
3
7
使用以下的一些想法 Plagiarism Detection 算法。
为了为每个ROM创建一个可比较的“签名”,随着小部分的变化而略有变化,生成类似于单词频率图的东西,但你可以对ROM的很短部分进行哈希运算,并记录哈希值的频率,而不是记录单词的频率。 不要只对一个部分进行哈希运算,然后从第一部分的末尾开始对下一部分进行哈希,而是使用滑动窗口,对从字节1开始的部分进行哈希计算,然后对从字节2开始、从字节3开始的相同大小的部分进行哈希计算,以此类推。这将抵消ROM中可变大小变化部分的影响。 如果你使用一个简单的哈希函数,比如每个8位字节的异或,这样你就可以很容易地计算下一个窗口位置的哈希,方法是用输出的8位对当前哈希进行异或运算,用输入的8位进行异或运算。另一种可选的哈希函数可能只是使用指令码字长度。这可能足以为表示机器指令的代码创建静态模式。重要的是,你需要一个哈希函数,在指令代码中产生常见的短序列,从而产生相同的哈希值。 你可能想要更少的哈希值,每个哈希值的频率更高,但不要走得太远,否则你的图会太平坦,导致比较困难。同样,不要走得太宽,否则你会有很多非常小的频率,使比较再次变得困难。
|
|
|
4
6
虽然这已经超过了“几天”,但我想我可能应该在这里添加我目前的解决方案。 第一步是单独压缩每个ROM并记录压缩后的大小,然后尝试将任意两个ROM归档在一起,看看结果大小与它们各自的压缩大小有多大不同。如果组合大小与单个大小的总和相同,则它们0%相似,如果大小与其中一个(最大的一个)相同,则完全相同。
|
|
|
5
3
我认为从数据压缩中借鉴的一些技术可能会很有趣:
大小的差异将给你一个粗略的估计,这些文件有多相似。
|
|
|
6
2
XDelta对于获得体面的二进制差异非常有用: http://xdelta.org |
|
|
7
1
您可以从存储以下内容开始 hash trees 只需要为每个ROM存储一组这样的哈希值,并且假设块大小恒定,所需的存储空间仅与ROM的大小成比例(但远低于ROM的大小)。所选块大小必须提供足够的粒度以确保准确性,例如:对于最小大小为128MiB的块,精度限制为1%,以及 Tiger-128 hash (类似于他们用来检查通过DirectConnect传输的文件的方法),1MiB的块大小是可以的,你可以将所有哈希存储在128*128/8=2048字节中!因此,使用10000个ROM只需要大约20MiB的空间。此外,您可以选择一个不太安全但更快和/或更小的哈希。添加/检查新ROM的相似性将需要以下内容:
正如你所看到的,这个问题在性能方面被简化为一个更简单的问题:检查更小的数据集的相似性。 |
|
|
8
1
|
|
|
9
1
正如Waylon Flinn所说,你可能需要一个二进制增量算法。这 rsync algorithm utility's documentation . |
|
|
10
1
这里的困难在于,由于您正在处理可执行代码,简单的更改可以在整个ROM中传播。所有值的地址和偏移量都可以通过添加单个变量或不添加操作指令来更改。这将使基于块的哈希变得毫无价值。 一个快速而肮脏的解决方案是用 difflib (或等效的w/你最喜欢的语言),因为它为你提供了一个滑动比较,可以处理数据的添加或删除。将ROM拆分为可执行文件和数据部分(如果可能的话)。数据部分可以直接与 similarity ratio calculated
不幸的是,这仍然是对您跟踪的ROM数量的O(n^2)操作,但可以通过(增量)聚类或基于频率的比较顺序来减轻,以减少所需的比较量。 |
|
|
user2995603 · 数组中相似项的序列 8 年前 |
|
|
Dan · 在TestComplete中使用“like”是可能的吗? 8 年前 |
|
|
zer02 · Rails:一种检查DB中重复项的方法?关联数据源 11 年前 |
|
|
Shani · 查找具有不同长度[闭合]的特征向量的相似性度量 12 年前 |