代码相似性检测工具
背景
最近由于工作需要,想找一个能够检查代码相似性的工具。这种工具主要有两个应用:
-
代码自身的冗余检查
-
查重,例如检查学生的编程作业是否有抄袭
工具
最后找到了两个工具sim
和moss
,具体实现算法还没有研究,但是moss
需要申请,并且通过网络使用,这样速度、灵活性和安全性都是有缺陷的,所以选择了sim
。
这个工具编译起来也很麻烦,而且没有mac的版本,幸好已经有人编了一个https://github.com/fanghon/antiplag/blob/master/sim_java.exe[Windows版本可执行文件],先用着。
扩展
由于我是要比较两个项目,并且按照相似性排序,但是sim
本身的参数似乎不支持,所以写了一个脚本(moss
后端不在本地,这种定制能力就做不了)
import os
dir1 = "*******"
dir2 = "*******"
target_file_list_1 = []
target_file_list_2 = []
def gen_file_list(dir_name, suffix_name):
temp = []
for root, dirs, files in os.walk(dir_name):
for file in files:
if file.endswith(suffix_name):
temp.append(os.path.join(root, file))
return temp
target_file_list_1 = gen_file_list(dir1, ".java")
target_file_list_2 = gen_file_list(dir2, ".java")
result = []
def parse_result(text):
for line in text.split("\n"):
if " % of " in line:
line_arr = line.split(" ")
result.append([line_arr[0], line_arr[-2], line_arr[3]])
break
total = len(target_file_list_1) * len(target_file_list_2)
cnt = 0
for from_f in target_file_list_1:
for to_f in target_file_list_2:
cnt += 1
ret = os.popen("sim_java.exe -p {} {}".format(from_f, to_f))
parse_result(ret.read())
print("{} / {}".format(cnt, total))
result.sort(key=lambda d: int(d[2]), reverse=True)
with open("./out.txt", 'w') as f:
for item in result:
f.write(str(item) + "\n")