摘要:
为了提高源程序代码之间相似性的检测效率,提出一种基于序列聚类的相似代码检测算法. 算法首先把源代码按照其自身的结构进行分段提取,然后对各个分段进行部分代码变换,再以带权重的编辑距离为相似度量标准对这些符号进行序列聚类,得到相似的程序代码片段,以达到对源程序进行相似功能检测的目的.
应用:
可以通过检测源程序中的相似代码对源程序进行简化,也可以查找出多个程序之间的相似功能,还能用于抄袭检测.
步骤:
1.提取出源代码中的功能段
2.以带权重的编辑距离为相似度量标准
3.通过聚类源程序代码序列的方法,查找出源程序中相似的代码功能段,以达到检测相似功能程序的目的.
1.问题定义:
大小:
字符数:
两条序列S1和S2之间的编辑距离:将 S1经过插入、删除、替代等操作变换成 S2所需要的最少操作次数.
签名:
eg。
签名距离:
1.1 带权重的编辑距离
本文对序列中各种不同类型的字符赋予不同的权重,根据字符的可替代性大小规定各个字符的权重. 如果是代表关键字的字符,所得到的权重就大一些,代表变量的字符得到的权重就比较小,因为相比之下,变量的可替代性要比关键字的可替代性大.
要对程序代码段进行聚类分析,首先要解决的问题就是怎样定义程序代码段之间的距离度量,以及怎样确定这 2 段代码是相似的. 本文定义一种带
权重的编辑距离( weight edit distance,WED) 来衡量2 个序列之间的距离,度量它们的相似性.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
1.2 序列间的相似度
=1-5/(7+7)=9/14
Smin被称为序列间的最小相似度阈值.
为了方便计算,根据Smin得出Dmax.
性质一:
签名距离反映了序列字母组成上的差异
权重编辑距离反映了 S1和 S2之间插入、删除、替换操作不同权重的差异
由于计算签名距离的时间复杂度 O( m + n) 远小于计算权重编辑距离的时间复杂度 O( mn) . 因此,根据性质 1,在判断序列是否相似时,可以首先
通过计算序列间的签名距离来进行初始过滤,再通过计算权重编辑距离来进行最后的判断.
2 基于带权重编辑距离的相似序列聚类算法
2.1 源程序代码的分段提取
检测源程序的相似代码,首先需要对源程序代码进行分段,提取出函数功能段. 在对源程序代码进行分段时,采用一种多级分段方法,把源代码分为不同标准下的多种分段,分段的标准有类、函数、语句,然后再对同一个级别下的各个分段代码进行处理.在查找相似代码时,由于函数功能段是整个源程序代码的主体,因此只需要使用第二级函数分段即可,对函数、语句和类的处理意义不大.
2.2 程序代码的部分转换
把关键字类型的代码转换成一个个数字,再计算权重编辑距离。
2. 3 符号序列的聚类
判 断 序 列 与 序 列 是 否 相 似
判断序列与簇是否相似
符号序列的聚类
3 实验与分析
由于在源程序中功能函数所占的比例很大,而且对于程序的功能取决定性作用,因此如果功能函数相似,那么基本上可以确定其所在的源程序也是相似的.从表 4 中可以看出,算法能够正确判断代码的相似性.
总结:
本文第一部分提出了两个概念:
1.带权重的编辑距离和签名距离
2.基于带权重的编辑距离和签名距离,来判断序列间的相似度,设定了一个阈值Smin,当超过Smin,则认为两个序列是相似的
第二部分讲诉了 基于带权重编辑距离的相似序列聚类算法:
1.源程序代码的分段提取(分段的标准有类、函数、语句,主要是函数类,因为函数功能段是整个源程序的主体)
2.分段后,对每一段中的关键字转换为数字,便于提取和处理
3.符号序列进行聚类:
a.判断序列与序列是否相似(根据前面距离)
b. 判断序列与簇是否相似(一个簇包含多个序列,把簇中的所有序列依次与该序列进行相似性判断,如果簇中有任意一个序列与该序列相似,就判定为该序列与该簇相似)
c.符号序列的聚类:
本文采用改进的基于密度的聚类算法对序列聚类,首先创建一个簇列表来存放聚类结果簇,对于存放在 map 中任意一个序列 Si,判断序列 Si与簇列表中的簇的相似关系,直到所有的序列 Si都被处理.此时的相似关系可能为 3 种情况: 1) 如果簇列表中没有簇与序列 Si相似,那么就新建一个簇存放该序列,并且把新创建的簇添加到簇列表中; 2) 如果簇列表中有一个簇与该序列相似,就把它加入到这个簇中,更新簇的特征值; 3) 如果簇列表中有多个簇与该序列相似,就把这几个簇合成一个新簇,再把序列 Si加入到新簇中,并且在簇列表中移除合并了的那几 个 簇,添 加 新 创 建 的 簇.
这篇论文仅仅只是提出了如何找出代码段中的相似代码。