CN108345468B - 基于树和序列相似度的编程语言代码查重方法 - Google Patents
基于树和序列相似度的编程语言代码查重方法 Download PDFInfo
- Publication number
- CN108345468B CN108345468B CN201810084588.1A CN201810084588A CN108345468B CN 108345468 B CN108345468 B CN 108345468B CN 201810084588 A CN201810084588 A CN 201810084588A CN 108345468 B CN108345468 B CN 108345468B
- Authority
- CN
- China
- Prior art keywords
- similarity
- variables
- sequence
- leaf nodes
- tree
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/70—Software maintenance or management
- G06F8/75—Structural analysis for program understanding
- G06F8/751—Code clone detection
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Debugging And Monitoring (AREA)
Abstract
本发明公开了一种基于树和序列相似度的编程语言代码查重方法,首先对待比较的两段程序代码预处理,包括去除注释信息、控制台输出语句和运算符等文本内容,确定查重的有效内容;然后根据程序的控制结构建树,并记录树中各个叶节点中变量的位置;其次为各叶节点中变量建立相对位置的序列,并基于此寻找函数间的相似变量,进而找出相似的叶节点,最终确定两段代码的相似度。本发明方法不仅去除了一些无关信息对查重结果的影响,而且针对变量重命名,修改函数位置和代码冗余问题,有较好的查重效果,通过本发明的方法,可开发相应的代码查重系统,提高代码查重效率,用于高校计算机编程类教学领域效果最佳。
Description
技术领域
本发明涉及数据分析及处理领域,特别涉及一种基于树和序列相似度的编程语言代码查重方法。
背景技术
现有的对程序代码查重方法有基于统计的方法、基于Token的方法、基于树的方法和基于图的方法。具体来说,基于统计的方法检测精度较低,该方法过度抽象,抗混淆能力很低,没有考虑程序的结构特点,空间复杂度低;基于Token的方法检测精确性较低,其精确性主要依赖于Token的选择和提取,其抗混淆能力低,难以应对冗余代码的植入,能够抵抗替换变量名、修改函数位置等混淆,时空复杂度较低,主要以文本结构及词法分析为主;基于树的方法检测精度总体较高,其检测精度主要依赖于树的精炼程度,抵抗混淆的能力较高,其方法考虑到语法特征,但难以应对修改函数位置、语句拆分等,其时空复杂度较高,主要在于构建树的成本较高;基于图的方法检测精确性总体高,其精确性依赖于图的精炼程度,该方法具有很高的抗混淆能力,充分考虑到程序的语法语义特征,能够抵御布局混淆,但难抵御部分数据及控制混淆,其时空复杂度高,构建代价很高,子图匹配是NP问题。总体而言,基于统计和基于Token的方法检测精度较低,基于图的方法精度较高,但其计算的时空复杂度较高,基于树的代码查重方法以其精度较高,时空复杂度较低的特点,适应于数据样本较少情况下的代码查重。
发明内容
本发明的目的在于克服现有技术的不足,提出一种基于树和序列相似度的编程语言代码查重方法,适用于编程语言的序列分析,支持C++和Java等高级语言的源代码比较,能快速、准确地给出与比较对象之间的相似度。
本发明解决其技术问题所采用的技术方案是:
一种基于树和序列相似度的编程语言代码查重方法,包括:
步骤1,去除代码中干扰相似度准确性的信息,将原程序中的代码转换成变量序列;
步骤2,按照程序结构,构建程序结构树,建立结构树的叶节点;
步骤3,建立叶节点中变量的绝对位置序列集合;
步骤4,比较叶节点,获得两叶节点间的相似度;
步骤5,比较两份程序代码所有的叶节点,获得两程序代码间的相似度。
优选的,所述步骤1,包括:
去除程序代码注释;
去除程序代码中输出语句中的字符串;
去除程序代码中控制台输入输出函数名和运算符号。
优选的,所述步骤3,包括:
统计叶节点内不同变量出现的个数;
根据每个变量出现的位置创建位置序列,获得变量位置序列集合;对叶节点中的变量做比较时,只比较变量的位置关系,不比较变量名称,对变量的位置序列进行序列分析,按照变量出现的顺序,获取变量的绝对位置序列。
优选的,所述步骤4,包括:
步骤4.1,获得变量的相对位置序列;
步骤4.2,基于Levenshtein距离,计算出不同序列间的相似度,求得相似度矩阵;
步骤4.3,依据变量间的相似度矩阵,求出叶节点的相似度。
优选的,不同序列间的相似度计算方法如下公式(1):
Sim(L1,L2)=1-Leve(L1,L2)/max(|L1|,|L2|) (1)
其中,(L1,L2)表示两变量相对位置序列,Leve(L1,L2)表示两序列的Levenshtein距离, max(|L1|,|L2|)表示两序列间的最大长度;
求得n*m相似度矩阵,其中n和m分别为两个叶节点变量的个数,矩阵元素记录了一组匹配对象和匹配对象之间的相似度。
优选的,所述依据变量间的相似度矩阵,求出叶节点的相似度,包括:
将矩阵中的元素按照相似度由大到小排序,多次有序的取其中的一个元素e,记录其匹配对象x、y和相似度s,遍历其他元素并记录各个元素的匹配对象x’、y’和s’;若元素中的x’或y’已经记录,那么跳过该元素,否则s与s’求和赋值于s,并记录x’和y’,计算出最大的s 值smax即为所求最大的相似度之和;并根据公式(2)计算出叶节点之间的相似度,如下:
S=smax/max(m,n) (2)。
其中,max(m,n)表示m和n最大的一个。
优选的,所述控制台输入输出函数名,包括:printf、scanf、cin和cout。
优选的,所述运算符号包括算术运算符、关系运算符和逻辑运算符。
本发明具有如下有益效果:
(1)本发明的基于树和序列相似度的编程语言代码查重方法,可有效检测出处理替换变量名、修改函数位置、冗余代码植入、同类控制块替换和变量拆分等常见的程序代码篡改方式;
(2)本发明首先去除与代码比较无关的信息,针对代码的关键信息进行查重,有较强的抗干扰能力;
(3)本发明以函数、枚举、联合和结构体结构为粒度构建叶节点,在提高查重精度的同时考虑到算法的时空复杂度,使得该算法准确高效;
(4)本发明在查重算法中,对变量的相对位置序列处理与分析,能够有效的解决变量重命名、冗余代码植入、代码重排的问题;
(5)本发明在寻求最大相似度之和的变量匹配过程中使用BlockSimilarity算法,相对于通用的KM算法,算法考虑到具体问题,执行效率更高。
以下结合附图及实施例对本发明作进一步详细说明,但本发明的一种基于树和序列相似度的编程语言代码查重方法不局限于实施例。
附图说明
图1为本发明实施例的基于树和序列相似度的编程语言代码查重方法的流程图;
图2为本发明实施例的典型的程序结构树;
图3为本发明实施例叶节点为函数的结构图;
图4为本发明实施例的代码查重系统界面图一;
图5为本发明实施例的代码查重系统界面图二。
具体实施方式
参见图1所示,本发明一种基于树和序列相似度的编程语言代码查重方法,包括:
步骤1,去除代码中干扰相似度准确性的信息,将原程序中的代码转换成变量序列。
步骤1在代码程序相似度检测过程中,排除了冗余代码的干扰,提高了查重结果的准确度,具体步骤包括:
步骤1.1,去除程序注释;如符号//之后的内容;去除/**/之间的内容;
步骤1.2,去除程序代码中输出语句中的字符串,该字符串表达的信息不影响程序逻辑;
步骤1.3,去除程序代码中常见控制台输入和输出函数名,包括但不限于printf、scanf、 cin和cout;去除运算符号,包括但不限于算术运算符、关系运算符和逻辑运算符。
去除干扰后剩下的词统称为变量,并形成变量序列。采用变量序列描述程序的执行逻辑,并为相似度分析做准备。
步骤2,按照程序结构,构建程序结构树,建立结构树的叶节点。
步骤2的目的在于将待检测的程序代码结构化,使查重过程充分考虑程序的结构特点,提高查重结果的准确度。具体地,为了使查重算法的时空复杂度尽可能低,并且检测精度尽可能高,以高级语言如C++或者Java中的函数、枚举、联合和结构体主要控制结构为粒度建立程序结构树的叶节点。典型的程序结构树参见图2所示,叶节点中的程序代码在步骤3中用于建立变量序列。
步骤3,建立叶节点中变量的绝对位置序列集合。
步骤3的目的在于分析叶节点,统计各个变量在叶节点中出现的位置关系,排除替换变量名称和同类控制块对相似度的干扰。
具体步骤为:
步骤3.1统计叶节点内变量出现的种类;
步骤3.2根据每个变量出现的位置创建位置序列,获得变量位置序列集合;对叶节点中的变量做比较时,只比较变量的位置关系,不比较变量名称,对变量的位置序列进行序列分析。
步骤4,比较叶节点,获得两叶节点间的相似度。
步骤4的目的在于找出叶节点中不同变量间的一组最佳匹配,并计算出叶节点间的相似度。具体步骤为:
步骤4.1,获得变量的相对位置序列。该步骤的目的在于减少替换变量对程序逻辑带来的影响。对叶节点中任意变量,根据所有绝对位置计算间隔,即相对位置,并形成该变量的相对位置序列。
步骤4.2,基于Levenshtein距离(Levenshtein距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数),计算变量相对位置序列之间的相似度。该步骤比较出不同序列间的相似度,不同序列间的相似度计算方式如公式(1):
Sim(L1,L2)=1-Leve(L1,L2)/max(|L1|,|L2|) (1)
其中,(L1,L2)为两变量相对位置序列,Leve(L1,L2)Leve(L1,L2)为两序列的Levenshtein 距离,max(|L1|,|L2|)Max(|L1|,|L2|)为两序列间的最大长度。
进一步的,通过公式(1),可求得n*m相似度矩阵,其中n和m分别为两个叶节点变量的个数,矩阵元素记录了一组匹配对象和匹配对象其之间的相似度。
步骤4.3,依据变量间的相似度矩阵,求出叶节点的相似度。该步骤的目的为减少同类控制块替换和变量拆分对相似度的影响。具体的将矩阵中的k个元素按照相似度由大到小排序,并对其进行k次遍历,对于第i次遍历(i≤k),从第i个元素开始,记录相比较的变量x、y和其相似度s,其中x、y为叶子结点中的变量,依次遍历剩余的k-i个元素,若比较元素中的变量x′或y′已经记录,则跳过该元素,否则,将其相似度s′与s相加赋值于s,并记录其变量x′、y′。从k次遍历中,取出最大的s值smax。最终叶节点之间的相似度S叶由相似度公式(2)得
S叶=smax/max(m,n) (2)
叶节点间的相似度参见表1所示的算法BlockSimilarity,BlockSimilarity算法的时间复杂度为O(k2),其中k=m*n。
表1
步骤5,比较两份程序代码所有的叶节点,获得两程序代码间的相似度。
该步骤的目的是获取两份程序代码间的相似度S,首先由叶子节点间的相似度,获取叶子节点间的相似度矩阵(M*N),其中M、N为两份代码的叶节点个数。将矩阵中的K个元素按照相似度由大到小排序,并对其进行K次遍历,对于第i次遍历(i≤K),从第i个元素开始,记录相比较的变量X、Y和其相似度S,其中X、Y为树中的叶子节点,依次遍历剩余的 K-i个元素,若比较元素中的叶子节点X'或Y'已经记录,则跳过该元素,否则,将其相似度 S'与S相加赋值于S,并记录其变量X'、Y'。从K次遍历中,取出最大的S值Smax。最终代码间的相似度S总由相似度公式(2)得
S总=Smax/max(M,N) (2)
如下结合程序代码1和程序代码2进行代码查重方法说明,具体实施方式如下:
步骤a,去除代码中干扰相似度的信息。
参见表2所示,对给出的待查重程序代码1和程序代码2,去除程序中的注释内容,控制台信息、运算符等信息,给出处理后的结果,参见表3所示,给出程序代码1和程序代码2中的变量序列,并保留了程序的结构。
表2
表3
步骤b,按照程序结构,构建程序结构树。
对处理的结果建树,在本实施例中,叶节点都为函数,用Fun表示,参见图3所示,程序代码1和程序代码2中,各自有6个叶节点。
步骤c,建立变量绝对位置序列集合。
计算叶节点中变量的种类,并计算出所在叶节点中出现的位置,参见表4所示。在叶节点中,给出变量的绝对位置。
表4
步骤d,比较叶节点,获得两叶节点间的相似度。
步骤d1,获取叶节点中变量的相对位置序列,由变量的位置序列,求出相同变量相邻位置的距离序列。
步骤d2,由相似度公式(1),计算出各个叶节点间,变量的相对位置序列间的距离,此步骤给出表5中叶节点Fun15中变量second与Fun24中变量sec之间的相似度Sim=1-2/4=0.5。其他序列间的距离也由公式(1)给出。
步骤d3,获得叶节点间的相似度矩阵,并根据该矩阵获取叶节点间的相似度。参见表5所示给出叶节点Fun15与Fun24中变量的相似度矩阵,并根据算法BlockSimilarity,求出叶节点 Fun15与Fun24间的相似度s=0.316。
表5
步骤e,求出两份程序代码间的相似度。获取叶节点间相似度矩阵,参见表6所示,并根据算法BlockSimilarity求得两份程序代码间的相似度S=70.86%。
表6
最后,代码查重系统主要界面如图4和5所示。
以上仅为本发明的较佳实施例,并不用以限制本发明,凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。
Claims (4)
1.一种基于树和序列相似度的编程语言代码查重方法,其特征在于,包括:
步骤1,去除代码中干扰相似度准确性的信息,将原程序中的代码转换成变量序列;
步骤2,按照程序结构,构建程序结构树,建立结构树的叶节点;
步骤3,建立叶节点中变量的绝对位置序列集合;
步骤4,比较叶节点,获得两叶节点间的相似度;
步骤5,比较两份程序代码所有的叶节点,获得两程序代码间的相似度;
所述步骤3,包括:
统计叶节点内不同变量出现的个数;
根据每个变量出现的位置创建位置序列,获得变量位置序列集合;对叶节点中的变量做比较时,只比较变量的位置关系,不比较变量名称,对变量的位置序列进行序列分析,按照变量出现的顺序,获取变量的绝对位置序列;
所述步骤4,包括:
步骤4.1,获得变量的相对位置序列;
步骤4.2,基于Levenshtein距离,计算出不同序列间的相似度,求得相似度矩阵;
步骤4.3,依据变量间的相似度矩阵,求出叶节点的相似度;
不同序列间的相似度计算方法如下公式(1):
Sim(L1,L2)=1-Leve(L1,L2)/max(|L1|,|L2|) (1)
其中,(L1,L2)表示两变量相对位置序列,Leve(L1,L2)表示两序列的Levenshtein距离,max(|L1|,|L2|)表示两序列间的最大长度;
求得n*m相似度矩阵,其中n和m分别为两个叶节点变量的个数,矩阵元素记录了一组匹配对象和匹配对象之间的相似度;
所述依据变量间的相似度矩阵,求出叶节点的相似度,包括:
将矩阵中的元素按照相似度由大到小排序,多次有序的取其中的一个元素e,记录其匹配对象x、y和相似度s,遍历其他元素并记录各个元素的匹配对象x’、y’和s’;若元素中的x’或y’已经记录,那么跳过该元素,否则s与s’求和赋值于s,并记录x’和y’,计算出最大的s值smax即为所求最大的相似度之和;并根据公式(2)计算出叶节点之间的相似度,如下:
S=smax/max(m,n) (2)
其中,max(m,n)表示m和n最大的一个。
2.根据权利要求1所述的基于树和序列相似度的编程语言代码查重方法,其特征在于,所述步骤1,包括:
去除程序代码注释;
去除程序代码中输出语句中的字符串;
去除程序代码中控制台输入输出函数名和运算符号。
3.根据权利要求2所述的基于树和序列相似度的编程语言代码查重方法,其特征在于,所述控制台输入输出函数名,包括:printf、scanf、cin和cout。
4.根据权利要求2所述的基于树和序列相似度的编程语言代码查重方法,其特征在于,所述运算符号包括算术运算符、关系运算符和逻辑运算符。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810084588.1A CN108345468B (zh) | 2018-01-29 | 2018-01-29 | 基于树和序列相似度的编程语言代码查重方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810084588.1A CN108345468B (zh) | 2018-01-29 | 2018-01-29 | 基于树和序列相似度的编程语言代码查重方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN108345468A CN108345468A (zh) | 2018-07-31 |
CN108345468B true CN108345468B (zh) | 2021-06-01 |
Family
ID=62960984
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201810084588.1A Active CN108345468B (zh) | 2018-01-29 | 2018-01-29 | 基于树和序列相似度的编程语言代码查重方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN108345468B (zh) |
Families Citing this family (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN109408114B (zh) * | 2018-08-20 | 2021-06-22 | 哈尔滨工业大学 | 一种程序错误自动修正方法、装置、电子设备及存储介质 |
CN109634594B (zh) * | 2018-11-05 | 2020-08-21 | 南京航空航天大学 | 一种考虑代码语句顺序信息的代码片段推荐方法 |
CN110399162B (zh) * | 2019-07-09 | 2021-02-26 | 北京航空航天大学 | 一种源代码注释自动生成方法 |
CN110795530B (zh) * | 2019-09-11 | 2022-10-04 | 无锡江南计算技术研究所 | 一种基于上下文的值特征提取系统及其方法 |
CN110990017B (zh) * | 2019-09-11 | 2022-09-09 | 无锡江南计算技术研究所 | 一种基于可信树的特征存储与匹配方法 |
CN111898343B (zh) * | 2020-08-03 | 2023-07-14 | 北京师范大学 | 一种基于短语结构树的相似题目识别方法和系统 |
CN112416431B (zh) * | 2020-11-23 | 2023-02-14 | 南京航空航天大学 | 一种基于编码序列表示的源代码片段成对比较方法 |
Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101446944A (zh) * | 2008-12-10 | 2009-06-03 | 苏州大学 | 一种自然语言句子的语义关系树的构造和比较方法 |
US9015682B1 (en) * | 2012-03-28 | 2015-04-21 | Google Inc. | Computer code transformations to create synthetic global scopes |
-
2018
- 2018-01-29 CN CN201810084588.1A patent/CN108345468B/zh active Active
Patent Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN101446944A (zh) * | 2008-12-10 | 2009-06-03 | 苏州大学 | 一种自然语言句子的语义关系树的构造和比较方法 |
US9015682B1 (en) * | 2012-03-28 | 2015-04-21 | Google Inc. | Computer code transformations to create synthetic global scopes |
Non-Patent Citations (1)
Title |
---|
Python程序设计题的查重研究;赵明洪;《中国优秀硕士学位论文全文数据库》;20160615(第06期);第7-41页 * |
Also Published As
Publication number | Publication date |
---|---|
CN108345468A (zh) | 2018-07-31 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN108345468B (zh) | 基于树和序列相似度的编程语言代码查重方法 | |
CN108446540B (zh) | 基于源代码多标签图神经网络的程序代码抄袭类型检测方法与系统 | |
CN106649260B (zh) | 基于评论文本挖掘的产品特征结构树构建方法 | |
CN109885479B (zh) | 基于路径记录截断的软件模糊测试方法及装置 | |
CN111459799B (zh) | 一种基于Github的软件缺陷检测模型建立、检测方法及系统 | |
US20070156749A1 (en) | Detection of patterns in data records | |
CN110362824B (zh) | 一种自动纠错的方法、装置、终端设备及存储介质 | |
Ueda et al. | On detection of gapped code clones using gap locations | |
US10866972B2 (en) | Systems and methods for trie-based automated discovery of patterns in computer logs | |
CN112733156B (zh) | 基于代码属性图的软件脆弱性智能检测方法、系统及介质 | |
CN112579155A (zh) | 代码相似性检测方法、装置以及存储介质 | |
US20080127043A1 (en) | Automatic Extraction of Programming Rules | |
CN112347271A (zh) | 基于文字语义识别的配电物联网设备缺陷辅助录入方法 | |
CN114817298A (zh) | 字段级数据血缘提取方法、装置、设备及存储介质 | |
CN106294139B (zh) | 一种软件代码中重复片段的检测提取方法 | |
CN113238937B (zh) | 一种基于代码精简与误报过滤的编译器模糊测试方法 | |
CN110737469A (zh) | 一种功能粒度上基于语义信息的源代码相似度评估方法 | |
CN111737694B (zh) | 一种基于行为树的恶意软件同源性分析方法 | |
CN116804980A (zh) | 一种二进制组件检索方法及装置 | |
CN111143448A (zh) | 一种知识库构建方法 | |
Higazy et al. | Web-based Arabic/English duplicate record detection with nested blocking technique | |
CN117390130A (zh) | 一种基于多模态表示的代码搜索方法 | |
Shi et al. | A novel detection approach for statement clones | |
CN117435246B (zh) | 一种基于马尔可夫链模型的代码克隆检测方法 | |
CN112698836B (zh) | 一种针对复杂用户评论的代码质量属性判断方法 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |