一种功能粒度上基于语义信息的源代码相似度评估方法

文档序号:1577089 发布日期:2020-01-31 浏览:31次 >En<

阅读说明:本技术 一种功能粒度上基于语义信息的源代码相似度评估方法 (Source code similarity evaluation method based on semantic information on functional granularities ) 是由 房春荣 史洋洋 蒋燕 陈振宇 李玉莹 于 2019-09-29 设计创作,主要内容包括:一种功能粒度上基于语义信息的源代码相似度评估方法,其特征是在功能粒度上使用标识符和控制流图对源码分别进行表示,其中功能是由函数和函数间的调用关系组成的介于源代码文件和函数之间的代码表示,计算功能对应的标识符和控制流图的嵌入向量,将控制流图中节点对应的代码片段用相应的标识符表示替换,再与控制流图的嵌入向量组合得到功能的嵌入向量,接着计算功能的嵌入向量之间的距离,得到源代码之间的相似度,可以较为准确的衡量Type-4克隆。(method for evaluating similarity of source code based on semantic information in function granularity is characterized in that the source code is respectively expressed in function granularity by using identifiers and control flow graphs, wherein functions are expressed by codes between a source code file and a function, which are formed by calling relations between functions, the identifiers corresponding to the functions and embedded vectors of the control flow graphs are calculated, code segments corresponding to the nodes in the control flow graphs are replaced by corresponding identifiers, the code segments are combined with the embedded vectors of the control flow graphs to obtain the embedded vectors of the functions, then the distance between the embedded vectors of the functions is calculated to obtain the similarity between the source codes, and Type-4 clone can be accurately measured.)

一种功能粒度上基于语义信息的源代码相似度评估方法

技术领域

本发明属于软件工程领域,尤其是代码表示和深度学习方法在软件工程领域的应用,用于检测代码相似度。

背景技术

源代码相似性度量是软件过程研究中常用的方法。度量源代码相似性的技术应用于代码克隆检测,代码修复和软件抄袭检测等研究领域。这些技术成功地应用于分析开源软件和本地代码库。当开发人员通过复制-粘贴-修改操作重用代码,或者实现一个和现有功能十分相似的功能时,就会导致代码克隆。因为代码克隆很容易导致软件缺陷的产生和版权侵犯,针对识别相似代码片段的代码克隆检测引起了人们极大的关注。

代码克隆可以根据不同的相似程度等级分为四种类型:

1)Type-1:除了注释和布局不同,其他相同的代码片段;

2)Type-2:除Type-1克隆之外,除变量名不同,其他代码片段相同;

3)Type-3:除Type-1和Type-2克隆之外,语句级别上不同,但是语法上类似的代码,比如代码片段的增加、删除、修改;

4)Type-4:实现相同功能的语法上不同的代码片段。

在这四种类型的代码克隆中,对于Type-4克隆(也称为功能克隆)的检测是最困难的。因为相同的功能的实现可能是有很大差别的,比如求和可以使用for循环语句和递归实现。因此仅仅通过代码片段的词法信息来衡量功能相似度是很困难的。

如今有很多检测代码克隆的方法,关键思想是使用代码的词法信息和语法信息来衡量代码间的相似度。现有的工具比如CCFinder和SourceCC将源码表示为标识符序列,然后通过比较子序列来检测克隆。Deckard引入了抽象语法树来比较两个代码片段结构上的相似度。CCFinder和SourceCC是典型的基于词法的方法,只考虑词法级别上源码的相似度,忽略语法信息。因此上述两种方法可以成功的检测词法克隆(即Type-1和Type-2类型克隆),但是在大部分情况下对于检测Type-3和Type-4克隆效果不好。另一方面,Deckard是典型的基于语法的方法,考虑了源代码的结构信息。尽管语法信息在检测Type-3克隆时有帮助,但是在检测Type-4克隆时还是无效的。现有的方法对于检测Type-4克隆效果不佳,但是在实际情况中Type-4克隆占有的比例很高,因此应当显示的考虑Type-4克隆。

发明内容

本发明要解决的问题是:当前的源代码相似度检测中,对于源代码语义上的相似度,即Type-4克隆检测效果不佳。

本发明的技术方案为:一种功能粒度上基于语义信息的源代码相似度评估方法,包括以下步骤:

1)将源代码在功能粒度上进行划分,主要通过以下几个步骤进行划分:

1.1)首先,使用joern获取除系统函数(scanf,printf等)外,每一个用户编写函数funck的调用关系图

Figure BSA0000191646690000021

其中k为函数唯一标识,n为被调用次数,code为代码片段在源代码中的位置{起始行,终止行,起始列,终止列},表示函数i中的代码片段code调用函数k;

1.2)然后,根据步骤1.1)中得到的函数调用关系,将所有FCG为空的函数构成功能集合Func={func1,...,funcn}中,funci(1≤i≤n)中初始有且仅有FCG为空的那个函数,n为所有的FCG为空的函数个数;

1.3)接着,对于功能集合Func中的每一个func,遍历func中的每一个函数,根据该函数的调用关系图FCG,将被调用函数及调用关系加入到func中,直到func中的函数个数不再变化,停止遍历;

1.4)最后,得到功能集合Func={func1,...,funcn},集合中的每一个元素表示源代码中的一个功能,功能包括函数以及函数间的调用关系。

2)对于每一个功能,首先将功能中所有的函数用抽象语法树表示;接着将抽象语法树的叶子节点取出来,叶子节点主要对应于函数中的标识符和常量,并将常量替换为其常量类型(<int>,<float>,<char>,<string>),得到函数的标识符表示;然后根据功能中函数的调用关系,将表示函数调用的代码片段对应的标识符表示,替换为被调用函数对应的标识符表示,直到功能中没有函数调用的代码片段。

3)对于每一个功能,首先将功能中所有的函数用控制流图G=(V,E)表示,其中V是节点的集合,节点包含一条或多条语句,E是有向边的集合,即语句间的控制流,值得注意的是每个控制流图有唯一的入口和出口节点;然后根据功能中函数的调用关系,将表示函数调用的代码片段对应的控制流图中的节点,替换为被调用函数的对应的控制流图,具体是将该节点的父亲节点与替换进来的控制流图的入口节点相连,该节点孩子节点与替换进来的控制流图的出口节点相连;递归的做下去直到每一个功能对应一个控制流图。

4)将功能的标识符表示作为word2vec算法的输入,计算每个标识符的词嵌入向量;将功能的控制流图作为HOPE算法的输入,计算控制流图中每个节点的嵌入向量。

5)获取控制流图中每一个节点包含的一条或多条语句中的标识符的嵌入向量,对节点中包含的所有标识符的嵌入向量进行平均池化操作,获取整个节点的标识符嵌入向量,并将其与步骤4)中的得到的节点的控制流图嵌入向量组合为新的嵌入向量:

其中,

Figure BSA0000191646690000032

表示控制流图中的节点的第k个标识符的嵌入向量,AvgPooling表示平均池化操作,EmbedVecCFG表示控制流图中节点的嵌入向量,EmbedVecComb表示节点结合源代码及其语义信息的嵌入向量。

6)根据功能对应控制流图的每个节点的嵌入向量,进行平均池化操作,得到整个功能的嵌入向量,计算两个功能的嵌入向量之间的欧几里得距离,小于阈值的两个功能代码片段判定为相似。

本发明的特点在于:1、通过函数调用图对源码进行表示划分,将源代码划分为包括函数和函数调用关系的功能;2、获取功能的抽象语法树,抽象语法树的叶子节点组成功能的标识符表示;3、获取功能的控制流图,获取控制流图中包含的源码语义信息;4、结合语义信息和词法信息,将功能表示为向量。将这4点结合,本发明可以提取功能中的词法信息和语义信息,通过获取源码中每一个功能的标识符和控制流图表示,将每一个功能表示为一个长度固定的向量,用向量间的距离来表示功能间Type-4代码克隆相似度的大小。

本发明的有益效果是:通过标识符表示和控制流图表示,捕获源码的在功能级别上的语义信息,将语义信息表示为向量后,可以检测Type-4代码克隆。

附图说明

图1为本发明整体流程图。

图2为词法、语法不同的实现相同功能的两份代码:Func1(左),Func2(右)。

图3为本发明中具体实例中两份代码的函数调用关系。

图4位本发明中具体实例中代码的控制流图(局部)。

具体实施方式

本发明中涉及的几项关键技术是Neo4j数据库、获取源码中抽象语法树、函数调用图和控制流图的joern工具、word2vec模型、HOPE模型。

1、Neo4j数据库

Neo4j是一个高性能的NoSQL图形数据库,它将结构化的数据存储在网络上而不是表中,是符合ACID标准的事务数据库,具有原生图存储和处理能力。本发明中,Neo4j数据库用来存储函数调用图和控制流图,可以依据函数id查询相应的函数调用图和控制流图。

2、joern工具

joern使用强大的C/C++解析器分析代码库,并通过存储在Neo4j图形数据库中的一个大型属性图表示整个代码库。本发明中,从Neo4j数据库中将函数对应的抽象语法树、控制流图、函数调用图取出来。

3、word2vec模型

word2vec是用来产生词向量的浅层、双层的神经网络,用来训练以重新构建词文本,训练完成之后,word2vec模型可用来映射每个词到一个向量。本发明中,将每一个功能的标识符表示作为word2vec模型的输入,输出为每一个标识符对应的向量。

4、HOPE模型

HOPE是图嵌入技术,用来训练以重新构建图,HOPE模型可用来将图中的每一个节点映射到一个向量。本发明中,将功能对应的控制流图中的每一个节点映射为一个向量。

下面用一个具体的示例来说明本方法的步骤,并展示结果。

我们选取了词法、语法信息不同,但是实现了相同功能,即Type-4克隆的两份源代码。

实验环境为:Ubuntu 16.04 LTS,运行内存8GB,存储512GBSSD

本发明的整体流程如图1所示,具体实施步骤如下:

1)实验中的两份源码,每份源码文件中包含两个函数main()和f(),两个源码文件实现了相同的功能,如图2所示;

2)使用joern分别获取两份源码的函数调用图,如图3所示,每一个不相连的函数调用图为源码中一个独立的功能,两份示例源码都仅包括一个功能;

3)使用joern获取功能中每一个函数的抽象语法树,取抽象语法树叶子节点,叶子节点即是该函数的标识符表示,将其作为word2vec模型的输入,可以得到每个标识符的词嵌入向量;

4)使用joern获取功能中每一个函数的控制流图,控制流图的节点包含一个或多个代码片段,然后根据功能中函数的调用关系,将表示函数调用的代码片段对应的控制流图中的节点,替换为被调用函数的对应的控制流图,递归的做下去,直到得到功能对应的控制流图,如图4所示;

5)将功能的标识符表示作为word2vec算法的输入,计算每个标识符的词嵌入向量,每个标识符的嵌入向量长度为50;将功能的控制流图作为HOPE算法的输入。计算控制流图中每个节点的嵌入向量,因为控制流图的抽象程度较高,控制流图中每个节点的嵌入向量长度设置为4;

6)获取控制流图中每一个节点包含的一条或多条语句中的标识符的嵌入向量,对节点中包含的所有标识符的嵌入向量进行平均池化操作,获取整个节点的标识符嵌入向量,并将其与节点的控制流图嵌入向量组合为新的嵌入向量,节点最终的嵌入向量长度为54;

7)根据功能对应控制流图的每个节点的嵌入向量,进行平均池化操作,得到整个功能的嵌入向量,计算两个功能的嵌入向量之间的欧几里得距离,小于0.01阈值的两个功能代码片段判定为相似。

10页详细技术资料下载
上一篇:一种医用注射器针头装配设备
下一篇:低精度机器学习操作的计算优化

网友询问留言

已有0条留言

还没有人留言评论。精彩留言会获得点赞!

精彩留言,会给你点赞!