首页 > 代码库 > 【代码相似论文笔记】基于序列聚类的相似代码检测算法

【代码相似论文笔记】基于序列聚类的相似代码检测算法

摘要:

        为了提高源程序代码之间相似性的检测效率,提出一种基于序列聚类的相似代码检测算法. 算法首先把源代码按照其自身的结构进行分段提取,然后对各个分段进行部分代码变换,再以带权重的编辑距离为相似度量标准对这些符号进行序列聚类,得到相似的程序代码片段,以达到对源程序进行相似功能检测的目的.

应用:

        可以通过检测源程序中的相似代码对源程序进行简化,也可以查找出多个程序之间的相似功能,还能用于抄袭检测.

 

 

步骤:

1.提取出源代码中的功能段

2.以带权重的编辑距离为相似度量标准

3.通过聚类源程序代码序列的方法,查找出源程序中相似的代码功能段,以达到检测相似功能程序的目的.

 

1.问题定义:

image

大小image

字符数imageimage

两条序列S1和S2之间的编辑距离image将 S1经过插入、删除、替代等操作变换成 S2所需要的最少操作次数.

签名imageimage

imageimage

eg。

签名距离imageimage

imageimageimageimage

 

1.1 带权重的编辑距离

    本文对序列中各种不同类型的字符赋予不同的权重,根据字符的可替代性大小规定各个字符的权重. 如果是代表关键字的字符,所得到的权重就大一些,代表变量的字符得到的权重就比较小,因为相比之下,变量的可替代性要比关键字的可替代性大.

image

要对程序代码段进行聚类分析,首先要解决的问题就是怎样定义程序代码段之间的距离度量,以及怎样确定这 2 段代码是相似的. 本文定义一种
权重的编辑距离( weight edit distance,WED)
来衡量2 个序列之间的距离,度量它们的相似性.

image

eg:

假如一个符号序列 S1= asdfght,另一个符号序列 S2= abcfght. 可以看出这 2 个序列中只有2 个符号不同,设定其中的 b、c、d 都为关键字类型的符号,而 s 为操作符类型的权重。

        POS:1  2  3  4  5  6  7

     序列S1:a  s  d  f  g  h  t

     序列S2:a  b  c  f  g  h  t

2个序列 S1和S2间的权重编辑距离为  image=3+2=5

1.2 序列间的相似度

2个序列 S1和S2之间的相似度image

 image=1-5/(7+7)=9/14

Smin被称为序列间的最小相似度阈值

imageimage

imageimage

为了方便计算,根据Smin得出Dmax.

性质一:

imageimage

image

签名距离image反映了序列字母组成上的差异

权重编辑距离image反映了 S1和 S2之间插入、删除、替换操作不同权重的差异

由于计算签名距离的时间复杂度 O( m + n) 远小于计算权重编辑距离的时间复杂度 O( mn) . 因此,根据性质 1,在判断序列是否相似时,可以首先
通过计算序列间的签名距离来进行初始过滤,再通过计算权重编辑距离来进行最后的判断.

 

2    基于带权重编辑距离的相似序列聚类算法

2.1   源程序代码的分段提取

检测源程序的相似代码,首先需要对源程序代码进行分段,提取出函数功能段. 在对源程序代码进行分段时,采用一种多级分段方法,把源代码分为不同标准下的多种分段,分段的标准有类、函数、语句,然后再对同一个级别下的各个分段代码进行处理.在查找相似代码时,由于函数功能段是整个源程序代码的主体,因此只需要使用第二级函数分段即可,对函数、语句和类的处理意义不大.

2.2    程序代码的部分转换

把关键字类型的代码转换成一个个数字,再计算权重编辑距离。

2. 3    符号序列的聚类

        判 断 序 列 与 序 列 是 否 相 似

         判断序列与簇是否相似

         符号序列的聚类

3    实验与分析

由于在源程序中功能函数所占的比例很大,而且对于程序的功能取决定性作用,因此如果功能函数相似,那么基本上可以确定其所在的源程序也是相似的.从表 4 中可以看出,算法能够正确判断代码的相似性.

image

 

 

 

 

 

 

总结:

本文第一部分提出了两个概念:

1.带权重的编辑距离和签名距离

2.基于带权重的编辑距离和签名距离,来判断序列间的相似度,设定了一个阈值Smin,当超过Smin,则认为两个序列是相似的

第二部分讲诉了 基于带权重编辑距离的相似序列聚类算法:

1.源程序代码的分段提取(分段的标准有类、函数、语句,主要是函数类,因为函数功能段是整个源程序的主体)

2.分段后,对每一段中的关键字转换为数字,便于提取和处理

3.符号序列进行聚类:

        a.判断序列与序列是否相似(根据前面距离)

        b. 判断序列与簇是否相似(一个簇包含多个序列,把簇中的所有序列依次与该序列进行相似性判断,如果簇中有任意一个序列与该序列相似,就判定为该序列与该簇相似)

        c.符号序列的聚类:

            本文采用改进的基于密度的聚类算法对序列聚类,首先创建一个簇列表来存放聚类结果簇,对于存放在 map 中任意一个序列 Si,判断序列 Si与簇列表中的簇的相似关系,直到所有的序列 Si都被处理.此时的相似关系可能为 3 种情况: 1) 如果簇列表中没有簇与序列 Si相似,那么就新建一个簇存放该序列,并且把新创建的簇添加到簇列表中; 2) 如果簇列表中有一个簇与该序列相似,就把它加入到这个簇中,更新簇的特征值; 3) 如果簇列表中有多个簇与该序列相似,就把这几个簇合成一个新簇,再把序列 Si加入到新簇中,并且在簇列表中移除合并了的那几 个 簇,添 加 新 创 建 的 簇.

 

 

这篇论文仅仅只是提出了如何找出代码段中的相似代码。

【代码相似论文笔记】基于序列聚类的相似代码检测算法