2013-12-15 35 views
0

我希望能够比较多个文件(最多30个),以便找到某种程度的相似性。它不需要完美我只是想要某种红旗,如果两个文件异常相似。这将是一个好方法吗?比较Python中两个java文件的相似性

+1

建造一个作弊探测器?我认为现在有这样的服务。 – user2357112

+1

定义“*相似*”和“*异常相似*”。 –

+1

你看过[difflib](http://docs.python.org/2/library/difflib.html)模块吗? – mgilson

回答

1

您可以使用正则表达式(通常称为正则表达式:python regex docs)。使用分组,您可以找到变量和函数名称,唯一的代码行(非空白或注释的行)等。

但是,创建一个足够智能的系统,能够自行检测相似性可能非常困难。如果您有某种方法可以获得两个文件中0到1之间的数字及其相似性,则可以在较高的阈值下对其进行测试。任何超过阈值(比如说0.97)都可以被认为是可疑的。

除了查看物理代码外,还可以观察文件中的代码密度。想象一下,如果你打印出一页代码并将其转为90度。你基本上得到每个文件上的行数的图表。使用它,您可以观察哪里有峰和谷,以查看代码密度更高或更低的位置。两个相似的文件可能具有相同或非常接近的代码密度。此外,使用这种方法,您不必担心寻找变量或函数名称,因为您没有太在意代码本身,而是如何组织它们。

1

充实@ mgilson的评论,这里是一个非常简单的开始:

def file_similarity(path1, path2): 
    "Return float in [0., 1.] giving some measure of file similarity." 
    import difflib 
    with open(path1, "rb") as f1, open(path2, "rb") as f2: 
     s = difflib.SequenceMatcher(
       lambda ch: ch in " \t", # don't sync on blanks or tabs 
       f1.read(), 
       f2.read()) 
    return s.ratio() 

阅读SequenceMatcher文档的更多。特别是,如果您有多个要比较的文件,重用对象(请参阅set_seq1()set_seq2()方法)效率会更高。如果您使用阈值,正如接受的答案建议的那样,请参阅real_quick_ratio()quick_ratio()方法以更多地缩短时间。

为了得到更好的结果,我首先通过规范化转换来提供文件,主要是用空格替换制表符(制表符和空格与字符比较的不同之处在于,比如'a''/',但区别在于人眼不可见)。删除所有空白行可能也会有帮助。