Skip to main content

一个简单的python代码抄袭检测工具

项目描述

这是一个简单的python代码抄袭检测工具,基本思想是规范化python AST表示并使用difflib来获取从引用代码到候选代码的修改。pycode_similar中定义的抄袭是候选代码抄袭了多少引用代码,这意味着交换引用代码和候选代码会得到不同的结果。

实现这个工具只花了我几个小时,所以在提高速度和准确性方面还有很长的路要走,但它在检测我们公司新员工作业的抄袭方面已经表现出色。

与苔藓相比

  • 纯python实现

  • 只包含一个源文件

  • 无第三方依赖(使用TreeDiff时 zss 除外)

  • 无需注册 Moss 账号

  • 无需网络即可访问 Moss

在我知道有一个Moss(用于衡量软件相似性)来确定程序的相似性之前,这个工具就诞生了。而且我尝试了很多方法来注册Stanford Moss的账号,但仍然无法获得一个有效的账号。所以,我在 pycode_similar 和 Moss 之间没有准确的比较。

安装

如果您没有太多时间,只需执行

$ pip install pycode_similar

它将在您的系统上安装模块(无需测试)。

此外,您可以复制并粘贴不需要第三方依赖的 pycode_similar.py。

用法

如果 pip install 正确,只需将其用作标准命令行工具。

$ pycode_similar
usage: pycode_similar [-h] [-l L] [-p P] [-k] [-m] files files

A simple plagiarism detection tool for python code

positional arguments:
  files       the input files

optional arguments:
  -h, --help          show this help message and exit
  -l L                if AST line of the function >= value then output detail (default: 4)
  -p P                if plagiarism percentage of the function >= value then output detail (default: 0.5)
  -k, --keep-prints   keep print nodes
  -m, --module-level  process module level nodes

pycode_similar: error: too few arguments

当然,您也可以将其用作 python 库。

import pycode_similar
pycode_similar.detect([referenced_code_str, candidate_code_str1, candidate_code_str2, ...], diff_method=pycode_similar.UnifiedDiff, keep_prints=False, module_level=False)

执行

该工具实现了两种差异方法:基于行的差异(UnifiedDiff)和基于树编辑距离的差异(TreeDiff),它们都在函数AST级别运行。

  • UnifiedDiff,diff归一化函数AST字符串行,幼稚但高效。

  • TreeDiff,diff 函数 AST,非常慢,结果对小函数不好。(取决于zss

因此,在 cmd 中运行此工具时,默认的 diff 方法是 UnifiedDiff。当用作库时,您可以切换到 TreeDiff。

测试

如果你有源代码,你可以运行测试

$ python pycode_similar/tests/test_cases.py

或执行

$ python pycode_similar.py pycode_similar/tests/original_version.py pycode_similar.py

ref: tests/original_version.py
candidate: pycode_similar.py
80.14 % (803/1002) of ref code structure is plagiarized by candidate.
candidate function plagiarism details (AST lines >= 4 and plagiarism percentage >= 0.5):
1.0 : ref FuncNodeCollector._mark_docstring_sub_nodes<24:4>, candidate FuncNodeCollector._mark_docstring_sub_nodes<27:4>
1.0 : ref FuncNodeCollector._mark_docstring_nodes<54:8>, candidate FuncNodeCollector._mark_docstring_nodes<57:8>
1.0 : ref FuncNodeCollector.generic_visit<69:4>, candidate FuncNodeCollector.generic_visit<72:4>
1.0 : ref FuncNodeCollector.visit_Str<74:4>, candidate FuncNodeCollector.visit_Str<78:4>
1.0 : ref FuncNodeCollector.visit_Name<83:4>, candidate FuncNodeCollector.visit_Name<88:4>
1.0 : ref FuncNodeCollector.visit_Attribute<89:4>, candidate FuncNodeCollector.visit_Name<88:4>
1.0 : ref FuncNodeCollector.visit_ClassDef<95:4>, candidate FuncNodeCollector.visit_ClassDef<100:4>
1.0 : ref FuncNodeCollector.visit_FunctionDef<101:4>, candidate FuncNodeCollector.visit_FunctionDef<106:4>
1.0 : ref FuncInfo.__init__<141:4>, candidate FuncInfo.__init__<161:4>
1.0 : ref FuncInfo.__str__<151:4>, candidate FuncInfo.__str__<171:4>
1.0 : ref FuncInfo.func_code<162:4>, candidate FuncInfo.func_code<182:4>
1.0 : ref FuncInfo.func_code_lines<168:4>, candidate FuncInfo.func_code_lines<188:4>
1.0 : ref FuncInfo.func_ast<174:4>, candidate FuncInfo.func_ast<194:4>
1.0 : ref FuncInfo.func_ast_lines<180:4>, candidate FuncInfo.func_ast_lines<200:4>
1.0 : ref FuncInfo._retrieve_func_code_lines<186:4>, candidate FuncInfo._retrieve_func_code_lines<206:4>
1.0 : ref FuncInfo._iter_node<208:4>, candidate FuncInfo._iter_node<228:4>
1.0 : ref FuncInfo._dump<232:4>, candidate FuncInfo._dump<252:4>
1.0 : ref FuncInfo._inner_dump<242:8>, candidate FuncInfo._inner_dump<262:8>
1.0 : ref ArgParser.error<267:4>, candidate ArgParser.error<291:4>
0.95: ref unified_diff<281:0>, candidate UnifiedDiff._gen<339:8>
0.92: ref FuncNodeCollector.__init__<18:4>, candidate FuncNodeCollector.__init__<20:4>
0.92: ref FuncNodeCollector.visit_Compare<108:4>, candidate FuncNodeCollector._simple_nomalize<117:8>
0.89: ref FuncNodeCollector.visit_Expr<79:4>, candidate FuncNodeCollector.visit_Expr<83:4>

单击此处 查看此差异 -> 0.92:参考 FuncNodeCollector.visit_Compare<108:4>,候选 FuncNodeCollector._simple_nomalize<117:8>

存储库

该项目托管在 GitHub 上。你可以在这里查看源代码:

https://github.com/fyrestone/pycode_similar

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

pycode_similar-1.4.tar.gz (15.6 kB 查看哈希

已上传 source

内置分布

pycode_similar-1.4-py2.py3-none-any.whl (10.0 kB 查看哈希

已上传 py2 py3