Page 137 - 《软件学报》2026年第7期
P. 137

2822                                                       软件学报  2026  年第  37  卷第  7  期


                    如表  4  所示, CENTRIS  从  100  个项目中识别出了   184  个组件, 精确率为   51.63%, 召回率为  47.26%. CENTRIS
                 仍依赖于函数诞生时间来处理公共函数的归属问题, 正如第                    2.1  节所述, 函数诞生时间的局限性使得公共函数的
                 归属判断不够准确, 从而引发假阳性. CAnalyzer 引入了文件粒度分析和更严格的阈值标准来判断                          TPL  的存在性,
                 从而在减少假阳性方面表现优异, 精确率达到了               90.63%. 此外, 由于  CENTRIS  的特征库仅包含     10 294  个  TPL, 导
                 致部分真实组件被遗漏, 从而产生了大量假阴性 (FN), 降低了召回率. 而                  CAnalyzer 使用了更为全面的特征库, 召
                 回率达到了    86.57%, 高于  CENTRIS.

                                         表 4 CAnalyzer 与相关工具有效性对比实验结果

                               工具          TP        FP       FN       Precision (%)  Recall (%)
                            CENTRIS [13]   95        89       106         51.63        47.26
                             TPLite [14]   172       102       29         62.77        85.57
                             OSSFP [15]    126       79        75         61.46        62.69
                             CAnalyzer     174       18        27         90.63        86.57

                    ● 与  TPLite 比较. TPLite 公开了源代码, 但未发布其特征库. 因此, 我们重新执行了              TPLite 的特征库构建过
                 程, 并使用与   CAnalyzer 相同的  TPL  数据集, 最终构建了一个包含       32 706  个  TPL  的特征库. TPLite [14] 在  CENTRIS
                 基于函数诞生时间推导        TPL  依赖关系的基础上, 将特征库构建成有向无环图, 并结合                PageRank [35] 算法和节点入度
                 的中心性过滤器来矫正函数诞生时间推导的不准确依赖关系. 与                     CENTRIS  相同, TPLite 也使用  10%  的阈值判断
                 TPL  是否为目标代码的有效成分.
                    如表  4  所示, CAnalyzer 在精确率上明显优于     TPLite. 其大多数假阳性 (FP) 案例, 源于报告的组件复用了真实
                 组件的部分代码. 这表明, 尽管        TPLite 采用了中心性过滤器来弥补函数诞生时间的局限性, 但它仍无法准确归属
                 公共函数, 从而导致如图       1  所示的假阳性问题. TPLite 重点关注      TPL  在全局图中的中心性, 通过评估         TPL  在图中
                 的重要性来决定保留哪些依赖关系. 如果某个               TPL  在全局图中的连接度不足, 相关依赖可能会被误删, 从而导致
                 函数被错误地归类为其他         TPL. 例如, 某个仅用于特定领域的核心          TPL, 仅由少数其他    TPL  复用, 但其在全局图中
                 的重要性较低, 指向该      TPL  的依赖关系可能会被删除, 进而导致这些函数被错误地归类为其他                     TPL.
                    相比之下, CAnalyzer 采用局部分析方法, 避免全局噪声干扰. 它将特征库划分为多个代码相似性较高的“家
                 族”, 并在每个家族内部分析        TPL  之间的依赖关系, 确保每个       TPL  自身的函数得到保留, 并去除非        TPL  的函数. 因
                 此, 在计算  TPL  和目标代码的重叠比例时, 分母能够准确反映每个                TPL  的实际函数数量, 避免了因过高的预设阈
                 值或匹配比例过小而导致的假阴性 (FN) 问题. 实验结果进一步验证, 尽管                    CAnalyzer 使用了严格的多重阈值, 但
                 仍能保留召回率.
                    ● 与  OSSFP  比较. 由于该商业工具未发布其特征库和源代码, 我们将                100  个项目上传到   OSSFP  网站在线检
                 测, 并使用标准集和      OSSFP  生成的结果, 手动检查其准确性. OSSFP        将  TPL  的函数划分为克隆函数、支持函数、
                 通用函数和核心函数, 通过设定阈值和函数诞生时间来去除前                     3  类函数, 最终仅基于核心函数生成         TPL  特征, 以
                 解决  TPL  之间的内部克隆问题. OSSFP      认为只要目标代码与        TPL  中的任一函数相同, 该     TPL  是目标代码的有效
                 成分. 根据  OSSFP  生成的结果, 我们确认了       126  个正确案例, 精确率和召回率分别为         61.46%  和  62.69%, 如表  4  所
                 示. OSSFP  结果中出现了大量如      git、lib  以及类似${library}的特殊变量和单个字母 (如       m) 形式的组件, 这些组件
                 可能是基于目标代码的目录结构进行分析的结果, 因此, 误报 (FP) 案例显著增加. 此外, 由于                       OSSFP  仅凭单个函
                 数相同即认为目标代码复用了           TPL, 这不满足库粒度复用检测的需求, 进而导致了             FP  的增加.
                    相较于   CAnalyzer, OSSFP  的召回率较低, 可能是由于特征库的范围不完整. OSSFP            基于  GitHub  的  23 427  个
                 C/C++存储库构建了      TPL  特征库, 但其规模仍小于我们从         15  个平台收集的    33 100  个  TPL  特征库. 此外, 由于
                 OSSFP  未公开更多   TPL  复用细节, 其结果的准确性只能通过           TPL  名称与标准集中的组件名称进行对比, 检查过
                 程可能引入误差, 从而影响了精确率和召回率的判断.
                    ● 假阳性 (FP) 分析. CAnalyzer 的假阳性主要源于公共函数归属的不准确, 具体表现如下.
   132   133   134   135   136   137   138   139   140   141   142