一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种软件复制率度量方法

2022-05-06 06:58:27 来源:中国专利 TAG:


1.本发明涉及软件检测领域,更具体的说是涉及一种软件复制率度量方法。


背景技术:

2.在软件开发过程中,开发人员经常通过复制有相似功能的代码并进行有针对性修改的方式提高开发效率,复制代码大量存在于软件之中,例如:研究表明,在linux系统中检测到了22.7%的重复代码,kamiya等人发现在jdk中存在29%的重复代码,而在某些软件中,重复现象甚至覆盖了50%的代码,并且有将近70%的软件中存在代码复制现象。
3.代码复制一定程度上为软件开发提供了帮助,开发者可以借鉴已有软件仓库中的代码加以修改或直接应用于自己的软件中以快速地完成软件开发。然而代码复制也会对软件产生负面影响,如:过度使用代码复制导致软件内部代码复杂和冗余,维护成本骤增;一些被复制的代码本身存在缺陷,当被复制到其他软件中时,就会导致整个软件的可靠性下降;软件开发人员违反软件开源许可证规则,违规对一些开源软件或源代码进行复制、修改和重用,侵犯软件版权。
4.近年来,大量工作对代码复制度量及检测技术进行了研究,提出了代码克隆(code clone)概念。代码克隆,也被称为重复代码或相似代码,指的是软件中存在相同或相似的源代码片段。bellon等人对代码克隆进行了分类,提出了4种不同类型的代码克隆定义,分别是完全相同的代码(类型1)、重命名/参数化的代码(类型2)、几乎相同的代码(类型3)和语义相似的代码(类型4),这样的定义在后续的研究中获得了广泛认可。
5.代码克隆的研究至今已有超过20年的历史,早期的代码克隆检测技术只考虑使用文本对源代码进行表征,只能检测类型1和一些简单的类型2代码克隆,但是许多类型3的代码克隆,是经过复制粘贴然后进行一定增删形成的,这种修改方式是开发人员经常使用的代码复用技术,而使用文本的表征方式却难以检测这类隐藏更深的代码克隆。为了解决这样的问题,研究者们使用了比文本更高层次的源代码表征方式,在词汇、语法和语义层面,提出了能够检测类型3甚至类型4代码克隆的检测技术。代码克隆问题也引起了工业界的关注,克隆检测工具被应用到生产开发环节中以控制代码质量,如基于textual的bcfinder、基于token的ccfinder和基于tree的clonedr等。
6.然而,上述方法主要关注于代码块或代码片段的克隆检测,无法对一个代码文件或一个完整软件的代码克隆情况进行度量。而在实际工作中,用户更关注软件的整体克隆情况,而不仅仅是软件中部分代码片段的克隆情况。另外,已有工作没有考虑到代码复杂度对代码克隆的严重影响,在代码克隆检测中,复杂度较低或功能较简单的代码更容易存在代码重复现象,但此类代码并不是需要重点检测的关键代码。
7.如何检测并输出软件整体的代码复制率报告,增加代码复制检测的实用性和可信度,是本领域技术人员亟需解决的。


技术实现要素:

8.有鉴于此,本发明提供了一种软件复制率度量方法,面向软件整体的代码复制率度量指标,着眼于整个软件,检测并输出软件整体的代码复制率报告,增加了代码复制检测的实用性和可信度。
9.为了实现上述目的,本发明采用如下技术方案:
10.一种软件复制率度量方法,包括以下步骤:
11.提取软件各代码文件中的函数集合;
12.通过所述函数集合计算复杂度信息与对应的权重计算函数综合复杂度;
13.通过所述函数集合计算不同克隆类型的代码克隆率与对应的权重计算函数综合克隆率;
14.根据函数综合复杂度和函数综合克隆率计算文件复制率及软件复制率。
15.可选的,提取软件各代码文件中的函数集合具体步骤如下:
16.输入待测软件;
17.过滤出待测软件中的代码文件,得到代码文件集合;
18.遍历代码文件集合,选取文件,生成与文件对应的抽象语法树,提取文件中的函数,得到函数集合。
19.可选的,计算函数综合复杂度的计算如下:
20.m(func
i,j
)=w
tot
(func
i,j
) w
sos
(func
i,j
) wvv(func
i,j
) wffc(func
i,j
);
21.其中,m(func
i,j
)表示函数的综合复杂度,w
t
表示代码时间复杂度权重,ws表示代码空间复杂度权重,wv表示代码圈复杂度权重,wf表示代码层次复杂度权重;o
t
(func
i,j
)指函数func
i,j
的代码时间复杂度,os(func
i,j
)指函数func
i,j
的代码空间复杂度,v(func
i,j
)指函数func
i,j
的代码圈复杂度,fc(func
i,j
)指函数func
i,j
的代码层次复杂度。
22.可选的,函数的层次复杂度fc(func
i,j
)计算如下:
23.fc(func
i,j
)=pin
func
(func
i,j
) fout
func
(func
i,j
);
24.其中,fin
func
(func
i,j
)表示函数func
i,j
的扇入数,fout
func
(func
i,j
)表示函数func
i,j
的扇出数。
25.可选的,代码圈复杂度v(func
i,j
)的计算如下:
26.v(func
i,j
)=e-n 2p;
27.其中,e和n分别表示函数func
i,j
对应控制流图中边和节点的数量,p表示图的连接组件数目。
28.可选的,函数综合克隆率的计算如下:
29.其中
30.其中,c
func
(func
i,j
)表示函数func
i,j
的综合克隆率,t
l
表示不同类型代码克隆的权重,c
l
(func
i,j
)代表函数func
i,j
存在不同类型克隆的克隆率。
31.可选的,文件复制率的计算如下:
[0032][0033]
其中,cf(fi)表示文件复制率,m(func
i,j
)表示函数func
i,j
的综合复杂度,c
func
(func
i,j
)表示函数func
i,j
的综合克隆率。
[0034]
可选的,软件复制率如下:
[0035][0036]
其中,c(f)为软件f的复制率,f为软件中的代码文件集合,kf(fi)为代码文件fi在软件中的权重,cf(fi)为fi的文件复制率。
[0037]
可选的,代码文件在软件中的权重计算如下:
[0038]
kf(fi)=w
sff
(fi) w
l
l(fi),其中ws w
l
=1;
[0039]
其中,kf(fi)表示代码文件fi在软件中的权重,ws表示文件调用关系复杂度的权重,w
l
表示文件代码规模的权重,l(fi)表示代码文件fi的规模,ff(fi)表示代码文件fi的调用关系复杂度。
[0040]
可选的,代码文件在软件中的调用关系复杂度计算如下:
[0041]ff
(fi)=fin
file
(fi) fout
file
(fi);
[0042]
其中,ff(fi)表示代码文件fi的调用关系复杂度fin
file
(fi)表示代码文件fi的扇入数,fout
file
(fi)表示fi的扇出数。
[0043]
经由上述的技术方案可知,与现有技术相比,本发明公开提供了一种软件复制率度量方法,具有以下有益效果:
[0044]
1、本发明可检测完整软件复制率并输出报告。首先,将软件以代码文件中的函数为最小单位进行划分,选择合适的代码克隆检测工具检测类型1、类型2、类型3和类型4的代码克隆率,加权计算得到函数综合克隆率,相较单一类型的克隆检测,本发明优势在于充分覆盖了各类型代码克隆,加权计算使得检测结果更加全面。第二,根据文件中每个函数的综合克隆率和综合复杂度,加权计算得到文件复制率,相较传统代码克隆计算方式,本发明使用复杂度分析相结合的方式,提高了文件复制率检测的客观性。第三,使用文件复制率与代码文件在软件中权重相结合的计算方式,得到软件复制率,优势在于本发明可以输出完整软件复制率,增加复制率检测的实用性和可信度,使得用户可以更加全面的掌握软件复制情况。
[0045]
2、本发明使用复杂度分析与代码克隆检测结合的方式,检测软件复制率。首先,通过计算函数的代码时间复杂度、代码空间复杂度、代码圈复杂度和代码层次复杂度,加权计算得到函数综合复杂度,相较传统的代码复杂度计算,使用综合复杂度来代表函数的复杂程度,不仅可以统计函数内部代码的复杂程度,还可以统计该函数在文件内调用和被调用情况,更全面的代表函数的复杂程度。第二,在计算文件复制率时,将函数综合复杂度与函数综合克隆率结合,加权计算得到文件复制率,有效避免了代码克隆检测中部分简单代码克隆率高,但对软件整体而言重要性低的问题。第三,在计算软件复制率时,将文件调用关系复杂度和文件代码规模作为权重与文件复制率结合,加权计算得到软件复制率,优点在于能够体现文件在整个软件中的重要程度,从而得到更合理的软件复制率。
附图说明
[0046]
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据
提供的附图获得其他的附图。
[0047]
图1为本发明的整体流程示意图;
[0048]
图2为本发明的文件及其中函数集合提取流程图;
[0049]
图3为本发明的计算函数综合复杂度的流程图;
[0050]
图4为本发明的代码克隆检测的流程图;
[0051]
图5为本发明的文件及软件复制率计算的流程图。
具体实施方式
[0052]
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
[0053]
本发明实施例公开了一种软件复制率度量方法,如图1所示,基本步骤如下:
[0054]
提取软件各代码文件的函数集合;
[0055]
计算函数综合复杂度;
[0056]
计算函数综合克隆率;
[0057]
根据函数综合复杂度和函数综合克隆率计算文件复制率及软件复制率具体的如下:
[0058]
在软件或代码库中,通常包含许多类型的文件,如代码文件、数据文件和解释文件等。可以使用识别文件后缀等方法过滤出软件中的代码文件,得到代码文件集合。然后对代码文件进行分析,将代码文件中的源代码转换为抽象语法树,提取出其中的函数集合。
[0059]
如图2所示,文件及其中函数集合提取的步骤如下:
[0060]
步骤1-1:起始状态,输入待检测软件;
[0061]
步骤1-2:过滤出软件中的代码文件,得到代码文件集合f={f1,f2,

,fi,

};
[0062]
步骤1-3:遍历代码文件集合f,选取文件fi,生成与其对应的抽象语法树,提取fi中的函数,得到fi中的函数集合funci={func
i,1
,func
i,2
,

,func
i,j
,

};
[0063]
步骤1-4:输出文件fi中的函数集合funci。
[0064]
步骤1-5:重复执行步骤1-3至1-4,直至f中所有代码文件遍历完毕。
[0065]
在代码克隆中结合复杂度分析,以更加合理地评价逻辑相对简单且被普遍使用代码的复制率,提高软件复制率检测的准确性和实用性。本发明中,复杂度分析包括对代码时间复杂度、代码空间复杂度、代码圈复杂度和代码层次复杂度的分析。
[0066]
对指定函数func
i,j
,代码时间复杂度o
t
(func
i,j
)指运行func
i,j
所需要的时间资源;代码空间复杂度os(func
i,j
)指运行func
i,j
所需要的空间资源;代码圈复杂度v(func
i,j
)是对func
i,j
中线性独立路径数的定量测量,可以用来衡量一个模块判定结构的复杂程度,定义如公式(2.1)。其中,e和n分别表示func
i,j
对应控制流图中边和节点的数量,p表示图的连接组件数目。
[0067]
v(func
i,j
)=e-n 2p#(2.1);
[0068]
在软件中,代码层次结构包含扇入和扇出两种方式,扇入是指直接调用该模块的上级模块个数,扇出是指该模块直接调用的下级模块个数,代码层次复杂度的定义如公式
(2.2)。其中,fc(func
i,j
)表示函数func
i,j
的层次复杂度,即函数func
i,j
的扇入扇出总数,fin
func
(func
i,j
)表示函数func
i,j
的扇入数,fout
func
(func
i,j
)表示函数func
i,j
的扇出数。
[0069]
fc(func
i,j
)=fin
func
(func
i,j
) fount
func
(func
i,j
)#(2.2);
[0070]
直观上,扇出大表示模块的复用程度高,该模块的复杂度高,需要控制和协调较多的下级模块;扇入大表示模块在文件中被调用程度高,许多其他模块需要使用该模块以完成功能,该模块在文件中较为重要。用代码时间复杂度、代码空间复杂度、代码圈复杂度与层次复杂度相结合的方式,既3种代码复杂度计算了函数内部代码的复杂程度,又通过代码层次复杂度分析了该函数在文件中的调用和被调用情况。相较传统的代码复杂度度量,该统计方式能更客观地表示模块复杂程度。
[0071]
可使信息熵、ahp层次法等权重计算方法计算3种代码复杂度和代码层次复杂度的权重,以加权计算函数的综合复杂度,计算公式如(2.3)。其中,m(func
i,j
)表示函数的综合复杂度,w
t
表示代码时间复杂度权重,ws表示代码空间复杂度权重,wv表示代码圈复杂度权重,wf表示代码层次复杂度权重。
[0072]
m(func
i,j
)=w
tot
(func
i,j
) w
sos
(func
i,j
) wvv(func
i,j
) wffc(func
i,j
)#(2.3);
[0073]
如图3所示,计算函数综合复杂度的步骤如下:
[0074]
步骤2-1:起始状态,输入所有代码文件的集合f;
[0075]
步骤2-2:依次遍历f中的文件fi;
[0076]
步骤2-3:依次遍历fi对应的函数集
[0077]
合funci={func
i,1
,func
i,2
,

,func
i,j
,

}中的函数func
i,j

[0078]
步骤2-4:计算代码时间复杂度o
t
(func
i,j
);
[0079]
步骤2-5:计算代码空间复杂度os(func
i,j
);
[0080]
步骤2-6:计算代码圈复杂度v(func
i,j
);
[0081]
步骤2-7:统计代码层次复杂度fc(func
i,j
);
[0082]
步骤2-8:根据代码时间复杂度、代码空间复杂度、代码圈复杂度和代码层次复杂度,加权计算该函数的综合复杂度m(func
i,j
);
[0083]
步骤2-9:重复步骤2-3至2-8,直至代码文件fi包含的函数集合遍历完毕;
[0084]
步骤2-10:重复步骤2-3至2-9,直至代码文件集合f中的所有文件遍历完毕;
[0085]
步骤2-10:输出代码文件集合f中所有函数的综合复杂度。
[0086]
bellon等人提出了4种代码克隆类型的定义,这样的定义在后续的研究中获得了广泛认可。
[0087]
类型1(完全相同的代码):除了空格、注释之外,两个代码片段完全相同;
[0088]
类型2(重命名/参数化的代码):两个代码片段除了变量名、类型名、函数名之外都相同;
[0089]
类型3(几乎相同的代码):有若干语句的增删,或使用了不同的标识符、文字、类型、空格、布局和注释,但是两个代码片段依然相似;
[0090]
类型4(语义相似的代码):相同功能的异构代码,在文本或者语法上不相似,但在语义上有相似性。
[0091]
代码克隆检测首选需要将代码转换为便于分析的格式,主要采用基于文本、基于词汇和基于语法3种表征方式。
[0092]
基于文本的表征方式将源代码当作文本编码,利用一系列文本相似度算法来检测代码克隆。这种根据源代码的字符串来进行检测的方法理论上只能检测类型1的代码克隆和一些基本的类型2代码克隆。虽然该方式克隆检测能力较低,但是因为只将待检测代码视为字符串进行比对,无需进行编译等操作,所以支持大多数编程语言的检测且鲁棒性较强。本发明使用基于文本的表征方式检测类型1的代码克隆。
[0093]
基于词汇表证方式也称为基于符号(token)表证方式,这种技术利用符号解析器将源代码分成符号序列,然后将符号序列组织成符号语句,最后把这些符号组成的语句进行比较。基于词汇的表征方式利用了更符合编译原理的符号序列,对源代码信息有了更进一步的利用。本发明使用基于符号的表征方式检测类型2的代码克隆。
[0094]
基于语法的代码表征方式主要使用语法树的方法,抽象语法树是源代码特有的一种表现形式,它是编译源代码的一个中间结果,以树的形式包含了源代码中的语法信息。在代码克隆检测中,基于树的方法会将源代码解析成抽象语法树作进一步的处理,利用树匹配等算法进行子树比较,以检测代码克隆片段。本发明使用基于语法表征方式检测类型3和类型4的代码克隆。
[0095]
在完成对不同类型代码克隆检测后,首先可使用信息熵、ahp层次法等权重计算方法计算权重,然后计算函数综合克隆率,如公式(3.1)。其中,c
func
表示函数综合克隆率,t
l
表示不同类型代码克隆的权重,c
l
(func
i,j
)代表函数func
i,j
存在不同类型克隆的克隆率。
[0096]
其中
[0097]
如图4所示,代码克隆检测的步骤如下:
[0098]
步骤3-1:起始状态,输入所有代码文件的集合f;
[0099]
步骤3-2:依次遍历f中的文件fi;
[0100]
步骤3-3:依次遍历fi对应的函数集
[0101]
合funci={func
i,1
,func
i,2
,

,func
i,j
,

}中的函数func
i,j

[0102]
步骤3-4:对函数func
i,j
进行源代码预处理与转换。
[0103]
步骤3-5:使用基于文本表征方式,检测函数func
i,j
的类型1代码克隆率c1(func
i,j
)。
[0104]
步骤3-6:使用基于符号表征方式,检测函数func
i,j
的类型2代码克隆率c2(func
i,j
)。
[0105]
步骤3-7:使用基于语法表征方式,检测函数func
i,j
的类型3和类型4代码克隆率c3(func
i,j
)和c4(func
i,j
)。
[0106]
步骤3-8:根据4个类型代码克隆率,加权计算该函数综合克隆率c
func
(func
ij
);
[0107]
步骤3-9:重复步骤3-3至3-8,直至代码文件fi包含的函数集合遍历完毕;
[0108]
步骤3-10:重复步骤3-3至3-9,直至代码文件集合f中的所有文件遍历完毕;
[0109]
步骤3-11:输出代码文件集合f下所有代码文件中函数的综合克隆率。
[0110]
根据上述步骤,将已经计算出的函数综合复杂度与函数综合克隆率结合计算文件复制率cf(fi),如公式(4.1)。其中,cf表示文件复制率,m(func
i,j
)表示函数func
i,j
的综合复杂度,c
func
(func
i,j
)表示函数func
i,j
的综合克隆率。
[0111]
[0112]
指定代码文件的与其他文件的调用关系包括扇入和扇出两种形式。代码文件的扇入是指在该文件中模块被软件中其他文件调用的次数;代码文件的扇出是指在该文件中模块调用软件中其他文件或模块的次数。计算代码文件调用关系复杂度,如公式(4.2)。其中,ff表示代码文件调用关系复杂度,fin
file
(fi)表示代码文件fi的扇入数,fout
file
(fi)表示代码文件fi的扇出数。
[0113]ff
(fi)=fin
file
(fi) fout
file
(fi)#(4.2);
[0114]
通过统计该代码文件在软件中的调用关系,并结合该文件代码规模,使用上文权重计算方法得到代码文件调用关系复杂度的权重和文件代码规模的权重,并得到代码文件在软件中的权重,如公式(4.3)所示。其中,kf表示代码文件在软件中的权重,ws表示文件调用关系复杂度的权重,w
l
表示文件代码规模的权重,可使用信息熵、ahp层次法等权重计算方法计算ws和w
l
的取值,l(fi)表示代码文件fi的规模,可使用统计代码文件中有效的代码行数或字符数等方法,得到文件代码规模。
[0115]
kf(fi)=w
sff
(fi) w
l
l(fi),其中ws w
l
=1#(4.3);
[0116]
最后,通过每个代码文件的权重和文件复制率,加权计算软件复制率c(f),如公式(4.4)所示。其中,c(f)为软件的复制率,f为软件中代码文件集合,kf(fi)为代码文件fi在软件中的权重,cf(fi)为文件fi的复制率。
[0117][0118]
如图5所示,文件及软件复制率计算的步骤如下:
[0119]
步骤4-1:起始状态,输入所有代码文件集合f及各文件中函数综合复杂度m和函数综合克隆率c
func

[0120]
步骤4-2:依次遍历f中的文件fi;
[0121]
步骤4-3:计算文件fi复制率cf(fi);
[0122]
步骤4-4:统计代码文件fi的调用关系复杂度ff(fi);
[0123]
步骤4-5:统计代码文件fi的文件规模l(fi);
[0124]
步骤4-6:根据l(fi)和l(fi)加权计算代码文件在软件中的权重kf(fi);
[0125]
步骤4-7:重复步骤4-2至4-6,直至代码文件集合f中的所有文件遍历完毕;
[0126]
步骤4-8:根据代码文件集合f中每个文件的复制率和权重计算软件的复制率c(f);
[0127]
步骤4-8:输出软件复制率。
[0128]
对所公开的实施例的上述说明,使本领域专业技术人员能够实现或使用本发明。对这些实施例的多种修改对本领域的专业技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本发明的精神或范围的情况下,在其它实施例中实现。因此,本发明将不会被限制于本文所示的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献