CN114780103B - 一种基于图匹配网络的语义类代码克隆检测方法 - Google Patents

一种基于图匹配网络的语义类代码克隆检测方法 Download PDF

Info

Publication number
CN114780103B
CN114780103B CN202210450356.XA CN202210450356A CN114780103B CN 114780103 B CN114780103 B CN 114780103B CN 202210450356 A CN202210450356 A CN 202210450356A CN 114780103 B CN114780103 B CN 114780103B
Authority
CN
China
Prior art keywords
code
node
var
data
operator
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Active
Application number
CN202210450356.XA
Other languages
English (en)
Other versions
CN114780103A (zh
Inventor
李姗姗
薛志鹏
余跃
姜志杰
董威
陈振邦
陈立前
徐如林
周海芳
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
National University of Defense Technology
Original Assignee
National University of Defense Technology
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by National University of Defense Technology filed Critical National University of Defense Technology
Priority to CN202210450356.XA priority Critical patent/CN114780103B/zh
Publication of CN114780103A publication Critical patent/CN114780103A/zh
Application granted granted Critical
Publication of CN114780103B publication Critical patent/CN114780103B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/436Semantic checking
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/70Software maintenance or management
    • G06F8/75Structural analysis for program understanding
    • G06F8/751Code clone detection
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06NCOMPUTING ARRANGEMENTS BASED ON SPECIFIC COMPUTATIONAL MODELS
    • G06N3/00Computing arrangements based on biological models
    • G06N3/02Neural networks
    • G06N3/04Architecture, e.g. interconnection topology
    • G06N3/044Recurrent networks, e.g. Hopfield networks
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06NCOMPUTING ARRANGEMENTS BASED ON SPECIFIC COMPUTATIONAL MODELS
    • G06N3/00Computing arrangements based on biological models
    • G06N3/02Neural networks
    • G06N3/08Learning methods
    • G06N3/084Backpropagation, e.g. using gradient descent

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • Software Systems (AREA)
  • General Physics & Mathematics (AREA)
  • Computational Linguistics (AREA)
  • Data Mining & Analysis (AREA)
  • Biophysics (AREA)
  • Evolutionary Computation (AREA)
  • General Health & Medical Sciences (AREA)
  • Molecular Biology (AREA)
  • Computing Systems (AREA)
  • Biomedical Technology (AREA)
  • Artificial Intelligence (AREA)
  • Mathematical Physics (AREA)
  • Life Sciences & Earth Sciences (AREA)
  • Health & Medical Sciences (AREA)
  • Machine Translation (AREA)

Abstract

本发明公开了一种基于图匹配网络的语义类代码克隆检测方法,目的是解决语义类克隆检测结果不准确的问题。技术方案是:构建由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成的代码克隆检测系统;使用语义类代码克隆数据集对代码向量生成模块中的深度学习模型进行训练;使用代码克隆检测系统对待检测代码进行代码补全、提取代码中间表示、构建代码语义图,训练后的代码向量生成模块将代码语义图转化为高维向量,再使用向量相似度计算器判断向量的相似度是否超过阈值以判断待检测代码是否是克隆代码。采用本发明可完整获取代码语义信息,有效检测语义类代码克隆,且在代码不可编译时仍能进行检测。

Description

一种基于图匹配网络的语义类代码克隆检测方法
技术领域
本发明涉及大型软件维护中的克隆检测技术,具体涉及一种基于图匹配网络的代码克隆检测方法。
背景技术
随着计算机的发展,计算机软件已经在社会各个领域得到了广泛的应用,在现代社会中扮演着举足轻重的角色,发挥了重要的作用。随着各行各业对软件系统的需求日益扩增,现代软件系统的代码规模逐渐扩大,导致现代软件系统的开发往往需要耗费大量的人力以及时间。为了提高现代软件系统开发人员在软件开发中的效率,开发人员在开发软件过程中往往会复用一些已有的代码。复用代码的方法主要包括从代码仓库中搜索满足需求的代码,对代码简要修改和复制到目标软件系统中、使用成熟的开发框架例如Spring、Tensorflow等、针对具体任务使用前人总结的设计模式。上述方法虽然提高了开发人员的软件开发效率,但也催生了代码克隆现象。代码克隆是指代码仓库中两段相同或相似的代码。根据已有的研究工作显示,代码克隆已经广泛的存在于现代软件系统之中。在Linux操作系统内核中包含27%-35%的代码存在代码克隆,在当前最大的代码仓库Github中,超过70%的代码都存在代码克隆。虽然重复使用已有的代码可以显著提升软件开发人员的开发效率,但是重复使用已有代码也有可能引入潜藏的漏洞,如在复用代码时,为根据上下文对代码进行更改,使得引入预期外的控制流或数据流。因此代码克隆检测尤为重要。利用代码克隆检测,软件维护人员可以根据已知的恶意程序代码或含有漏洞的代码检测在软件中其他可能潜藏的恶意软件代码和含有漏洞的代码。
根据两段代码的相似程度的不同,一般将代码克隆分为四类。第一类代码克隆指除了注释和空格不同,其他都相同的两段代码。第二类代码克隆指仅仅函数名或变量名不同的两段代码。第三类代码克隆指在保持语法结构不变的基础上,在代码语句上略有增删的两段代码。第四类代码克隆也叫做语义类代码克隆,指语法结构不同,但是代码语义相同的两段代码。针对代码克隆的种类不同,现有主要有基于匹配和基于深度学习的方法检测代码克隆。基于匹配的代码克隆检测方法,主要通过将代码进行一些转换,再根据代码转换之后的表示形式,利用对应的相似比较算法,判断两段代码是否相似。例如Zu Yue等人在ASE2020会议上发表的文章“CCGraph:a PDG-based code clone detector withapproximate graph matching(一种利用相似图匹配算法的基于程序依赖图的克隆检测方法,简称CCGRAPH)”,将代码转化为包含其数据流信息和控制流信息的程序依赖图。为了比较两段代码的程序依赖图的相似性,他们使用Weisfeiler-Lehman图核算法来比较两个图的相似性,最后根据两个图的相似性是否超过既定阈值来判断两段代码是否是克隆代码。基于匹配的克隆检测方法速度较快,不需要前期准备工作,并且在前三种类型的代码克隆检测中可以取得较好的准确率和召回率。但是在解决语义类代码克隆问题时,基于匹配的克隆检测方法的准确率和召回率都有显著下降,导致开发人员在查找语义类克隆检测时,仍然需要花费大量的人力物力检查匹配的克隆检测方法的输出结果。基于深度学习的代码克隆检测方法是使用深度学习模型将代码转化为可以表示其含义的高维向量,通过训练深度学习模型,可以使克隆代码的向量在高维空间之中更近似。在判断一对代码是否是克隆代码时,使用训练好的深度学习模型将他们转化为高维向量,根据代码向量距离判断两段代码是否是克隆代码。例如Hao Yu等人在ICPC2019会议上发表的文章“Neural detectionof semantic code clones via tree-based convolution(基于树型卷积的语义代码克隆检测方法,简称TBCCD)”,将代码转化为抽象语法树,然后利用树型卷积模型将代码的抽象语法树转化为向量,最后比较代码向量的相似度判断代码是否为克隆代码。基于深度学习的代码克隆方法可以更有效的理解代码的语义,因此可以有效检测出语义类代码克隆。但是目前的基于深度学习的代码克隆检测方法主要使用以LSTM网络为代表的基于文本的深度学习模型,只学习了代码的文本和语法信息,在准确率和召回率仍有待提高。
综上,如何提供一种检测语义类代码克隆的方法,更好地挖掘代码中的信息,更好地使用深度学习模型学习代码语义,使得代码克隆检测更准确,是本领域技术人员正在探讨的热点问题。
发明内容
本发明要解决的技术问题是针对语义类克隆检测结果不准确,代码语义信息获取不全面问题,提供一种基于图匹配网络的代码克隆检测方法。此方法基于深度学习检测代码克隆的方法框架,抽取代码的数据流控制流信息构建代码语义图,更完整的提取代码语义信息。使用图匹配网络,可以更有效地学习代码语义图的语义信息,进而更准更全地查找语义类代码克隆。
为解决上述问题,本发明的技术方案是:首先构建由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成的代码克隆检测系统。然后使用语义类代码克隆数据集对代码向量生成模块中的深度学习模型进行训练,调整深度学习网络模型参数。最后使用代码克隆检测系统对用户输入的待检测代码进行代码补全、提取代码中间表示、构建代码语义图,训练后的代码向量生成模块将代码语义图转化为对应的高维向量V1和V2,再使用向量相似度计算器判断向量的相似度是否超过既定阈值。
本发明包含以下步骤:
第一步,构建代码克隆检测系统。代码克隆检测系统由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成。
代码补全模块与代码中间表示提取模块相连,使用JCoffee-1.0工具(见P Gupta等人在ICSME会议上发表的文献“JCoffee:Using Compiler Feedback to Make PartialCode Snippets Compilable”使用编译器反馈来使代码片段可编译,下载地址:https://github.com/piyush69/JCoffee)对输入的代码对C1,C2分别进行补全,得到补全后的代码对C‘1,C‘2,使C‘1,C‘2可以进行编译,将C‘1,C‘2发送给代码中间表示提取模块。
代码中间表示提取模块与代码补全模块、语义图构建模块相连,将从代码补全模块接收的C‘1,C‘2分别进行编译,提取C‘1,C‘2编译过程中的代码中间表示,构成代码中间表示对R1,R2。将R1,R2发送给语义图构建模块。
语义图构建模块与代码中间表示提取模块、代码向量生成模块相连,从代码中间表示提取模块接收R1,R2,从R1,R2中提取代码的常量、变量、操作符、API、数据流和控制流信息,分别构建可以表示代码语义的语义图,得到语义图对G1,G2,将G1,G2发送给代码向量生成模块。
代码向量生成模块与语义图构建模块、向量相似度计算器相连,从代码向量生成模块接收G1,G2,使用图匹配网络(见Y Li等人在PMLR2019的文献“Graph matchingnetworks for learning the similarity of graph structured objects”:使用图匹配网络来学习图结构目标的相似性)将G1,G2分别映射为高层向量空间中的两个代码向量V1,V2,将V1,V2发送给向量相似度计算器。
向量相似度计算器与代码向量生成模块相连,计算V1,V2的向量相似度SIM,根据SIM是否超过设定的阈值来判断V1,V2所表示的代码对C1,C2是否属于语义类代码克隆。
第二步,代码补全模块采用代码补全方法补全数据集中的代码。方法为:
2.1使用BigCloneBench数据集作为训练代码,BigCloneBench数据集来自JSvajlenko等人发表在ICSME2015会议上的文献“Evaluating clone detection toolswith bigclonebench”:使用Bigclonebench检验代码克隆检测工具。其中BigCloneBench数据集包含44种功能的代码,共8961段代码。在构建克隆代码对时,从BigCloneBench数据集中任意抽取两段代码可以构成一个代码对,若抽取的两段代码功能相同,则为克隆代码对,否则为非克隆代码对。从BigCloneBench数据集中总共可以构建11,241,933对克隆代码以及69,057,588对非克隆代码。由于从BigCloneBench数据集中构建的代码对数量庞大,使用全部的代码对讲消耗过多的时间和资源,因此在使用时仅仅从所有代码对中选择N(80299521=11,241,933+69,057,588≥N≥10,000)对代码以及对应的标注作为训练集用于模型训练。由于BigCloneBench数据集中存在代码不可编译,无法提取其代码中间表示,因此需要对代码进行补全。
2.2令可编译代码集合Data={};
2.3令变量n=1;
2.4从训练集中抽取第n个代码段CCn,判断CCn是否可编译,若CCn可编译,转2.5,否则转2.6;
2.5将CCn加入Data中,令n=n+1,转2.9;
2.6使用JCoffee-1.0工具补全CCn,得到补全后的代码CC′n,转2.7;
2.7判断CC′n是否可编译,若可编译,转2.8,否则转2.9;
2.8将CC′n加入Data中,令n=n+1,转2.9;
2.9若n≥N,说明Bigclonebench数据集中的所有代码均已经过补全,令补全后的Data中数据总数M=n,将补全后的Data发送给代码中间表示提取模块,转第三步;否则转2.4;
第三步,代码中间表示提取模块从代码补全模块接收可编译代码集合Data,采用代码中间表示提取方法从Data中提取代码中间表示,构建代码中间表示集合IR。具体方法为:
3.1令代码中间表示集合IR={};
3.2令变量m=1;
3.3从Data中抽取第m个代码CCm,若CCm为JAVA语言代码,转3.4;若为C语言代码,则转3.5;
3.4提取JAVA代码的代码中间表示,方法为:
3.4.1使用JavaC编译代码CCm,得到二进制文件Classm
3.4.2根据二进制文件Classm,使用Soot-4.1.0工具(见R Vallée-Rai等人在CASC1999会议上的文献“Soot:A Java bytecode optimization framework”:Soot:一个JAVA字节码优化框架,下载地址:http://soot-oss.github.io/soot/)提取代码的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.5利用LLVM-9.0工具(见C Lattner等人在CGO2004会议上发表的文献“LLVM:Acompilation framework for lifelong program analysis&transformation”LLVM:一个程序分析和转化的编译器框架,下载地址:https://releases.llvm.org/download.html)编译代码CCm,得到代码CCm的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.6若m>M,说明已为所有可编译代码提取代码中间表示,将代码中间表示集合IR发送至语义图构建模块,转第四步;若m≤M,转3.3。
第四步,语义图构建模块从代码表示提取模块接收代码中间表示集合IR,采用语义图集合构建方法根据IR构建语义图集合SG,方法为:
4.1令语义图集合SG={};
4.2令变量p=0;
4.3从IR中抽取第p个代码中间表示Rp,由于代码的中间表示中常常包含了语义无关的噪音,例如所使用的编译器类型,或编译过程中的通用信息等,而语义相关的关键信息通常是指代码中实际实现代码语义的指令,因此为了构建语义图首先需要从Rp中提取关键语义表示信息,过滤无用噪音信息。方法是:
4.3.1初始化关键语义表示信息队列Sp为空;
4.3.2初始化变量a=1,初始化标识flag=0;
4.3.3判断Rp的第a行代码
Figure BDA0003617008140000051
是否包含函数名,若包含函数名,说明此时已检索到代码中间表示关键指令信息起始位置,转到4.3.5,否则转到4.3.4;
4.3.4令a=a+1,若a≤Rp的长度,转4.3.3;若a>Rp的长度,转4.3.12;
4.3.5将
Figure BDA0003617008140000052
加入到Sp中,令a=a+1;
4.3.6由于根据代码生成的指令在“{}”符号的范围内,因此根据判断
Figure BDA0003617008140000053
是否包含符号“{”或“}”可判断当前中间表示行是否为中间表示的起始位置、结束位置或中间位置。若
Figure BDA0003617008140000054
包含符号“{”,说明
Figure BDA0003617008140000055
为中间表示语句块的开始位置,转4.3.7;若
Figure BDA0003617008140000056
包含符号“}”,说明
Figure BDA0003617008140000061
为中间表示语句块的结束位置,转4.3.9;若
Figure BDA0003617008140000062
既不包含“{”,也不包含“}”,说明
Figure BDA0003617008140000063
为中间表示语句块的中间位置,转4.3.8;
4.3.7令flag=1,表示开始存储中间表示关键指令信息,转4.3.10;
4.3.8若flag=1,将
Figure BDA0003617008140000064
加入到Sp中,转4.3.10;
4.3.9令flag=0,表示停止存储中间表示关键指令信息,转4.3.11;
4.3.10令a=a+1,转4.3.6;
4.3.11令a=a+1,若a小于Rp的长度,转4.3.3,否则转4.3.12;
4.3.12得到关键语义表示信息队列Sp,Sp中的元素为过滤掉了无用噪音信息的Rp中的代码,转4.4;
4.4语义图构建模块采用语义图构建方法根据Sp构建语义图Gp。方法是:
4.4.1初始化语义图Gp为空,即初始化语义图Gp的节点集合Vp、数据流边集合E_datap和控制流边集合E_controlp为空;
4.4.2语义图构建模块为Gp的节点集合Vp添加变量节点,方法是:
4.4.2.1初始化变量k=1;
4.4.2.2判断Sp第k个元素
Figure BDA0003617008140000065
是否为变量声明语句,若是变量声明语句,转4.4.2.3向Vp中添加变量节点;否则转4.4.2.4;
4.4.2.3利用正则表达式从
Figure BDA0003617008140000066
中提取变量var以及var的类型type,根据变量var以及var的类型type,以三元组的形式构建变量节点(var,type,vvar),vvar是变量节点的标识,表示此节点的类型为变量节点,vvar中存储的值为var,var数据类型为type,将变量节点(var,type,vvar)加入Vp中;
4.4.2.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,转到4.4.3;否则转4.4.2.2;
4.4.3语义图构建模块为Gp的节点集合Vp添加语句块节点,方法是:
4.4.3.1初始化变量k=1;
4.4.3.2判断Sp第k个元素
Figure BDA0003617008140000067
是否为语句块声明语句,即判断
Figure BDA0003617008140000068
中是否包含关键词“label%”,若包含“label%”,转4.4.3.3向Vp中添加语句块节点;否则转4.4.3.4;
4.4.3.3利用正则表达式从
Figure BDA0003617008140000069
中提取语句块标识符marker,根据标识符marker,以二元组的形式构建语句块标识符节点(marker,vcontrol),vcontrol是语句块标识符节点的标识,表示此节点类型为语句块标识符节点,vcontrol中存储的值为marker,将语句块标识符节点(marker,vcontrol)加入Vp中;
4.4.3.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,转到4.4.4;否则转4.4.3.2;
4.4.4语义图构建模块为语义图Gp添加操作符节点、数据流边和控制流边,操作符节点包括函数调用节点、运算符节点、取值操作符节点,方法是:
4.4.4.1初始化变量k=1;
4.4.4.2初始化变量u=1;
4.4.4.3判断Sp中第k个元素
Figure BDA0003617008140000071
是否为语句块声明语句,即是否包含关键词“label%”,若是语句块声明语句,转4.4.4.4提取当前语句块的语句块标识符节点;否则转4.4.4.5;
4.4.4.4利用正则表达式从
Figure BDA0003617008140000072
中提取语句块标识符marker,对变量u赋值,使u=marker,说明当前的中间表示语句属于语句块标识符节点(u,vcontrol)所代表的语句块,vcontrol表示此节点类型为语句块标识符节点,vcontrol中存储的值为u;
4.4.4.5判断
Figure BDA0003617008140000073
是否为函数调用语句,即判断
Figure BDA0003617008140000074
是否包含“invoke”关键词,若包含“invoke”,转4.4.4.6向Gp的节点集合Vp中添加函数调用节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.6使用正则表达式从
Figure BDA0003617008140000075
中提取调用函数的函数名method、函数调用的输入变量varin、函数的返回值变量varreturn。根据函数名method,以二元组的形式构建函数调用节点(method,vinvoke),vinvoke是构建函数调用节点的标识,表示此节点类型为函数调用节点,vinvoke中存储的值为method,将函数调用节点(method,vinvoke)加入Vp中。在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(method,vinvoke),econtrol-flow),表示函数调用节点(method,vinvoke)属于语句块标识符节点(u,vcontrol)所代表的语句块,econtrol-flow表示添加的边的属性为控制流边。在Gp的数据流边集合E_datap中以三元组形式添加两条数据流边,分别为((varin,type,vvar),(method,vinvoke),edata-flow)和((method,vinvoke),(varreturn,type,vvar),edata-flow),说明数据从变量节点(varin,type,vvar)输入函数调用节点(method,vinvoke)进行函数调用计算,经过函数调用计算得到的数据从函数调用节点(method,vinvoke)输出到变量节点(varreturn,type,vvar),edata-flow表示添加的边的属性为数据流边;
4.4.4.7判断Sp中第w个元素
Figure BDA0003617008140000076
是否为数据运算语句,即是否包含关键词“/”、“%”、“+”、“-”、“*”、“cmp”中的任意一个,若是数据运算语句,转4.4.4.8向Vp中添加运算符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.8使用正则表达式从
Figure BDA0003617008140000081
中提取数据运算的运算符op、参与运算的变量varin、运算的结果变量varreturn。根据运算符op,以二元组的形式构建运算符节点(op,voperator),voperator是运算符节点的标识,表示此节点为运算符节点,voperator中存储的值为op,将运算符节点(op,voperator)加入Vp中。在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(op,voperator),econtrol-flow),表示运算符节点(op,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块。在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(op,voperator),edata-flow)和((op,voperator),(varreturn,type,vvar),edata-flow),表示数据从变量节点(varin,type,vvar)输入运算符节点(op,voperator),运算后的数据从运算符节点(op,voperator)输出到变量节点(varreturn,type,vvar);
4.4.4.9判断Sp中第w个元素
Figure BDA0003617008140000082
是否为数组取值语句,即是否包含取值操作符“getelem”,若
Figure BDA0003617008140000083
包含关键词“getelem”,转4.4.4.10向Gp中添加操作符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.10使用正则表达式从
Figure BDA0003617008140000084
中提取数组变量varin,并提取结果变量varreturn。以二元组的形式构建取值操作符节点(getelem,voperator),表示运算符节点voperator中存储的值为取值操作符getelem,将取值操作符节点加入Vp中。在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(getelem,voperator),econtrol-flow),表示取值操作符节点(getelem,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块。在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(getelem,voperator),edata-flow),和((getelem,voperator),(varreturn,type,vvar),edata-flow),表示数组中的数据从数组变量节点(varin,type,vvar)输入取值操作符节点(getelem,voperator),经过取值操作从数组变量中得到的数据从取值操作符节点(getelem,voperator)输出到结果变量节点(varreturn,type,vvar);
4.4.4.11判断Sp中第w个元素
Figure BDA0003617008140000085
是否为判断语句或跳转语句,即是否包含关键词“goto”或“if”,若
Figure BDA0003617008140000086
包含关键词“goto”或“if”,转4.4.4.12向Gp中添加控制流边;否则转4.4.4.15;
4.4.4.12使用正则表达式从
Figure BDA0003617008140000087
中提取判断语句或跳转语句的目标语句块节点标识符newmarker。在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(newmarker,vcontrol),econtrol-flowr),表示程序执行时将从当前语句块标识符节点(u,vcontrol)所代表的语句块跳转到语句块标识符节点(newmarker,vcontrol)所代表的语句块。
4.4.4.13判断Sp中第w个元素
Figure BDA0003617008140000091
是否为赋值语句或类型转换语句,即是否包含关键词“=”,若
Figure BDA0003617008140000092
包含关键词“=”,转4.4.4.14向Gp中添加数据流边;否则转4.4.4.15;
4.4.4.14使用正则表达式从
Figure BDA0003617008140000093
中提取输入变量varin以及输出变量varreturn。在Gp的数据流边集合E_datap中以三元组的形式添加数据流边((varin,type,vvar),(varreturn,type,vvar),edata-flow),说明数据从变量varin输出到变量varreturn中。
4.4.4.15令k=k+1,若k大于Sp的长度,说明得到Gp,将Gp加入语义图集合SG中,转4.5;否则,转到4.4.4.3;
4.5若p大于代码中间表示数据集IR的大小,则得到语义图集合SG,转第五步;否则令p=p+1,转4.3;
第五步,根据语义图集合SG制作代码向量生成模块所需的训练数据集。方法为:
5.1令变量i=1;
5.2初始化训练数据集TrainingSet={};
5.3随机从语义图集合SG中任意抽取两个语义图,令第i次抽取的语义图为
Figure BDA0003617008140000094
Figure BDA0003617008140000095
Figure BDA0003617008140000096
Figure BDA0003617008140000097
所对应的代码功能相同,则标注Labeli为True,表示
Figure BDA0003617008140000098
Figure BDA0003617008140000099
所对应的代码为克隆代码;否则标注Labeli为False,表示
Figure BDA00036170081400000910
Figure BDA00036170081400000911
所对应的代码不为克隆代码;令第i个三元组
Figure BDA00036170081400000912
将Di放入训练数据集TrainingSet,转5.4;
5.4令i=i+1,若i>10,000,则训练集制作完成,将训练数据集TrainingSet发送到代码向量生成模块,转第六步;否则转5.3;
第六步:采用TrainingSet训练代码向量生成模块,得到可以表示语义图信息的图匹配网络。具体方法是:
6.1设置训练图匹配网络所需参数。方法是:
6.1.1设置图匹配网络包含网络层数T=4;
6.1.2设置图匹配网络学习率ir=0.001;
6.1.3设置训练轮数num_epochs=50;
6.1.4初始化训练轮数epochs=0;
6.2令变量i=1;
6.3从训练数据集TrainingSet中抽取第i个数据Di
Figure BDA00036170081400000913
6.4采用第一初始化方法初始化
Figure BDA00036170081400000914
中节点的向量值与边的权重值,得到初始化后的第一语义图
Figure BDA0003617008140000101
方法如下:
6.4.1使用Word2vec模型(见T Mikolov等人2013年发表在arxiv网站的文献“Efficient Estimation of Word Representations in Vector Space”,有效的表示文字在向量空间)初始化
Figure BDA0003617008140000102
中节点的向量值。从
Figure BDA0003617008140000103
的节点集合Vi 1中顺序选择节点x,x∈Vi 1,将节点x中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点x的初始化向量
Figure BDA0003617008140000104
6.4.2令
Figure BDA0003617008140000105
的数据流边集合
Figure BDA0003617008140000106
中每条边的权重值为1;
6.4.3令
Figure BDA0003617008140000107
的控制流边集合
Figure BDA0003617008140000108
中每条边的权重值为-1;
6.5采用第二初始化方法初始化
Figure BDA0003617008140000109
中节点的向量值与边的权重值,得到初始化后的第二语义图
Figure BDA00036170081400001010
方法如下:
6.5.1使用Word2vec模型初始化
Figure BDA00036170081400001011
中节点的向量值。从
Figure BDA00036170081400001012
的节点集合Vi 2中顺序选择节点z,z∈Vi 2,将节点z中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点z的初始化向量
Figure BDA00036170081400001013
6.5.2令
Figure BDA00036170081400001014
的数据流边集合
Figure BDA00036170081400001015
中每条边的权重值为1;
6.5.3令
Figure BDA00036170081400001016
的控制流边集合
Figure BDA00036170081400001017
中每条边的权重值为-1;
6.6采用迭代更新方法更新第一语义图
Figure BDA00036170081400001018
中各节点的向量表示,得到第一最终语义图
Figure BDA00036170081400001019
迭代更新方法如下:
6.6.1初始化变量t=1;
6.6.2从
Figure BDA00036170081400001020
的节点集合Vi 1中顺序选择第一节点x,x∈Vi 1,若
Figure BDA00036170081400001021
的节点集合Vi 1中所有节点都已被选择,则转6.6.7;否则转6.6.3;
6.6.3计算在第t次迭代时,
Figure BDA00036170081400001022
中的节点与
Figure BDA00036170081400001023
的相似性,方法是:
6.6.3.1从
Figure BDA00036170081400001024
的节点集合Vi 2中顺序选择第二节点,令第二节点为z,z∈Vi 2,若
Figure BDA00036170081400001025
的节点集合Vi 2中所有节点都已被选择,则转6.6.3.3;否则转6.6.3.2;
6.6.3.2计算x与z的相似度αz→x
Figure BDA00036170081400001026
其中
Figure BDA00036170081400001027
指x在t-1次迭代后的向量表示,
Figure BDA00036170081400001028
指z在t-1次迭代后的向量表示,
Figure BDA00036170081400001029
Figure BDA00036170081400001030
中任意一个不是z的节点在t-1次迭代后的向量表示,转到6.6.3.1;
6.6.3.3计算在第t次迭代时x与
Figure BDA00036170081400001031
的节点集合Vi 2中所有节点的相似度和
Figure BDA00036170081400001032
Figure BDA00036170081400001033
6.6.4计算在第t次迭代时,第一语义图
Figure BDA00036170081400001034
中与x有边相连的其他节点即第三节点y传递给x的消息向量和,方法是:
6.6.4.1在
Figure BDA0003617008140000111
中除x外的节点集合Vi 1-x中顺序选择第三节点,令第三节点为y,记连接x和y的边为exy,若Vi 1-x中的所有节点都已被选择,则转6.6.4.4;否则转6.6.4.2;
6.6.4.2判断边exy是否存在于
Figure BDA0003617008140000112
的数据流边集合
Figure BDA0003617008140000113
Figure BDA0003617008140000114
的控制流边集合
Figure BDA0003617008140000115
中,若存在,转6.6.4.3;否则转6.6.4.1;
6.6.4.3计算
Figure BDA0003617008140000116
中y对x的消息向量my→x
Figure BDA0003617008140000117
其中SUM为求和函数,
Figure BDA0003617008140000118
指x在t-1次迭代后的向量表示,
Figure BDA0003617008140000119
指y在t-1次迭代后的向量表示,exy指连接x和y的边的权重值,转到6.6.4.1;
6.6.4.4计算在第t次迭代时,第一语义图
Figure BDA00036170081400001110
中的x与其有边相连的所有第三节点y对x传递的消息向量和
Figure BDA00036170081400001111
Figure BDA00036170081400001112
6.6.5更新
Figure BDA00036170081400001113
中x在第t次迭代后的向量表示
Figure BDA00036170081400001114
Figure BDA00036170081400001115
其中GRU表示门控循环神经网络,表示利用门控循环神经网络,根据第t-1次迭代后x节点的向量
Figure BDA00036170081400001116
Figure BDA00036170081400001117
中与节点x相连的其他节点传递的消息向量和
Figure BDA00036170081400001118
x与
Figure BDA00036170081400001119
的节点集合Vi 2中所有节点的相似度和6.6.3.3中计算得到的
Figure BDA00036170081400001120
生成第t次迭代后的向量表示
Figure BDA00036170081400001121
6.6.6令t=t+1。若t小于T,转6.6.2;否则说明迭代更新完毕,得到第一最终语义图
Figure BDA00036170081400001122
转6.7;
6.7采用6.6所述迭代更新方法更新
Figure BDA00036170081400001123
中各节点的向量表示,得到第二最终语义图
Figure BDA00036170081400001124
6.8计算
Figure BDA00036170081400001125
的向量表示Vi 1
Figure BDA00036170081400001126
其中MLP为多层感知器模型,表示利用多层感知器模型将
Figure BDA00036170081400001127
中所有节点的向量汇总为向量Vi 1,其中
Figure BDA00036170081400001128
为经过T轮迭代后得到的最终语义图
Figure BDA00036170081400001129
中各个节点的向量值;
6.9计算
Figure BDA00036170081400001130
的向量表示Vi 2
Figure BDA00036170081400001131
6.10利用余弦相似度函数比较Vi 1,Vi 2的相似度。
Figure BDA00036170081400001132
判断SIM是否大于相似度阈值α,一般0.7≤α<1,若是,则认为
Figure BDA00036170081400001133
Figure BDA00036170081400001134
所对应的代码是克隆代码,即模型预测结果Labelpredict=True,否则
Figure BDA00036170081400001135
Figure BDA00036170081400001136
所对应的代码不为克隆代码,模型预测结果Labelpredict=False;
6.11若Labelpredict不等于Labeli,则转6.12;否则转6.15;
6.12若Labeli=False,跳转到6.13;若Labeli=True则跳转到6.14;
6.13计算模型调整值Loss=-(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.14设置向量调整值Loss=(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.15令i=i+1,若i大于语义图数据集SG的大小,说明已训练完一轮,转6.16;否则转6.3;
6.16令epochs=epochs+1,若epochs等于num_epochs,说明训练完毕,得到了可以表示语义图信息的图匹配网络,也即得到了训练后的代码向量生成模块,转第七步;否则转6.2,开始新一轮训练;
第七步:使用代码克隆系统检测用户输入的一对待检测代码C1,C2,判断C1,C2是否是克隆代码对,方法是:
7.1令待检测代码集合Test={C1,C2};
7.2代码补全模块采用第二步所述代码补全方法对待检测代码集合Test进行代码补全,得到补全后可编译的待检测代码集合Test_Data={C‘1,C‘2};
7.3代码中间表示提取模块采用第三步所述代码中间表示提取方法从对Test_Data提取代码中间表示,构建待检测代码集合的代码中间表示集合Test_IR,Test_IR={R1,R2};
7.4语义图生成模块采用第四步所述语义图集合构建方法根据Test_IR构建待检测代码集合的语义图集合Test_SG={G1,G2};
7.5训练好的代码向量生成模块根据Test_SG中的第一语义图G1和第二语义图G2,生成其对应的向量值V1和V2,方法如下;
7.5.1采用6.4所述第一初始化方法初始化G1,得到初始化后的语义图IG1,采用6.5所述第二初始化方法初始化G2得到初始化后的语义图IG2;;
7.5.2采用6.6所述迭代更新方法迭代更新初始化语义图IG1和IG2中节点的向量,分别得到最终语义图FG1和FG2
7.5.3计算FG1的向量值V1
Figure BDA0003617008140000121
7.5.4计算FG2的向量值V2
Figure BDA0003617008140000122
7.6训练好的向量生成模块利用余弦相似度函数比较V1和V2的相似度。
Figure BDA0003617008140000123
Figure BDA0003617008140000131
判断SIM是否大于相似度阈值α,若SIM>α,则认为G1和G2所对应的代码是克隆代码,即模型预测结果Labelpredict=True;若SIM≤α,G1和G2所对应的代码不为克隆代码,模型预测结果Labelpredict=False。
采用本发明可以达到以下技术效果:
1、采用本发明可以有效的检测语义类代码克隆。采用本发明在BigCloneBench数据集上对本文方法在检测克隆代码的效果进行测试。经过12小时的模型训练,可以有效检测到BigCloneBench中超过44%的代码克隆,并且保证58%的准确率。而已有方法“Neuraldetection of semantic code clones via tree-based convolution”(基于树型卷积的代码克隆语义检测)在检测到37%代码克隆时,仅能取得31%的准确度。
2、本发明第三步中利用编译器在编译代码过程中,对代码的中间表示信息,更准确完整地挖掘到代码中的语义信息(即有效信息),在第四步中根据挖掘出的代码关键语义信息,构建语义图,可以更好的表达代码中间表示中的语义信息。在第六步中使用图匹配网络更好的挖掘代码语义特征。相比于基于字符或者基于语法的克隆检测方法,本发明基于图匹配网络的方法可以更准确的提取代码的实际语义,因此本发明也取得了超过其他方法的代码克隆检测效果。
3、本发明在第二步对输入代码克隆检测系统的代检测代码进行了补全,使其在不可编译时,仍能使用本发明进行代码克隆检测,具有良好的泛用性。
附图说明:
图1为本发明整体流程图。
图2为本发明第一步构建的代码克隆检测系统逻辑结构图。
具体实施方式
下面结合附图对本发明进行说明。图1是本发明整体流程图。如图1所示,本发明包括以下步骤:
第一步,构建代码克隆检测系统。代码克隆检测系统如图2所示,由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成。
代码补全模块与代码中间表示提取模块相连,使用JCoffee-1.0工具对输入的代码对C1,C2分别进行补全,得到补全后的代码对C‘1,C‘2,将C‘1,C‘2发送给代码中间表示提取模块。
代码中间表示提取模块与代码补全模块、语义图构建模块相连,将从代码补全模块接收的C‘1,C‘2分别进行编译,提取C‘1,C‘2编译过程中的代码中间表示,构成代码中间表示对R1,R2。将R1,R2发送给语义图构建模块。
语义图构建模块与代码中间表示提取模块、代码向量生成模块相连,从代码中间表示提取模块接收R1,R2,从R1,R2中提取代码的常量、变量、操作符、API、数据流和控制流信息,分别构建可以表示代码语义的语义图,得到语义图对G1,G2,将G1,G2发送给代码向量生成模块。
代码向量生成模块与语义图构建模块、向量相似度计算器相连,从代码向量生成模块接收G1,G2,使用图匹配网络将G1,G2分别映射为高层向量空间中的两个代码向量V1,V2,将V1,V2发送给向量相似度计算器。
向量相似度计算器与代码向量生成模块相连,计算V1,V2的向量相似度SIM,根据SIM是否超过设定的阈值来判断V1,V2所表示的代码对C1,C2是否属于语义类代码克隆。
第二步,代码补全模块采用代码补全方法补全数据集中的代码。方法为:
2.1使用BigCloneBench数据集作为训练代码,BigCloneBench数据集包含44种功能的代码,共8961段代码。在构建克隆代码对时,从BigCloneBench数据集中任意抽取两段代码可以构成一个代码对,若抽取的两段代码功能相同,则为克隆代码对,否则为非克隆代码对。从BigCloneBench数据集中总共可以构建11,241,933对克隆代码以及69,057,588对非克隆代码。从所有代码对中选择N(80299521=11,241,933+69,057,588≥N≥10,000)对代码以及对应的标注作为训练集用于模型训练。由于BigCloneBench数据集中存在代码不可编译,无法提取其代码中间表示,因此需要对代码进行补全。
2.2令可编译代码集合Data={};
2.3令变量n=1;
2.4从训练集中抽取第n个代码段CCn,判断CCn是否可编译,若CCn可编译,转2.5,否则转2.6;
2.5将CCn加入Data中,令n=n+1,转2.9;
2.6使用JCoffee-1.0工具补全CCn,得到补全后的代码CC′n,转2.7;
2.7判断CC′n是否可编译,若可编译,转2.8,否则转2.9;
2.8将CC′n加入Data中,令n=n+1,转2.9;
2.9若n≥N,说明Bigclonebench数据集中的所有代码均已经过补全,令补全后的Data中数据总数M=n,将补全后的Data发送给代码中间表示提取模块,转第三步;否则转2.4;
第三步,代码中间表示提取模块从代码补全模块接收可编译代码集合Data,采用代码中间表示提取方法从Data中提取代码中间表示,构建代码中间表示集合IR。具体方法为:
3.1令代码中间表示集合IR={};
3.2令变量m=1;
3.3从Data中抽取第m个代码CCm,若CCm为JAVA语言代码,转3.4;若为C语言代码,则转3.5;
3.4提取JAVA代码的代码中间表示,方法为:
3.4.1使用JavaC编译代码CCm,得到二进制文件Classm
3.4.2根据二进制文件Classm,使用Soot-4.1.0工具提取代码的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.5利用LLVM-9.0工具编译代码CCm,得到代码CCm的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.6若m>M,说明已为所有可编译代码提取代码中间表示,将代码中间表示集合IR发送至语义图构建模块,转第四步;若m≤M,转3.3。
第四步,语义图构建模块从代码表示提取模块接收代码中间表示集合IR,采用语义图集合构建方法根据IR构建语义图集合SG,方法为:
4.1令语义图集合SG={};
4.2令变量p=0;
4.3从IR中抽取第p个代码中间表示Rp,方法是:
4.3.1初始化关键语义表示信息队列Sp为空;
4.3.2初始化变量a=1,初始化标识flag=0;
4.3.3判断Rp的第a行代码
Figure BDA0003617008140000151
是否包含函数名,若包含函数名,说明此时已检索到代码中间表示关键指令信息起始位置,转到4.3.5,否则转到4.3.4;
4.3.4令a=a+1,若a≤Rp的长度,转4.3.3;若a>Rp的长度,转4.3.12;
4.3.5将
Figure BDA0003617008140000152
加入到Sp中,令a=a+1;
4.3.6若
Figure BDA0003617008140000153
包含符号“{”,说明
Figure BDA0003617008140000154
为中间表示语句块的开始位置,转4.3.7;若
Figure BDA0003617008140000155
包含符号“}”,说明
Figure BDA0003617008140000156
为中间表示语句块的结束位置,转4.3.9;若
Figure BDA0003617008140000157
既不包含“{”,也不包含“}”,说明
Figure BDA0003617008140000161
为中间表示语句块的中间位置,转4.3.8;
4.3.7令flag=1,表示开始存储中间表示关键指令信息,转4.3.10;
4.3.8若flag=1,将
Figure BDA0003617008140000162
加入到Sp中,转4.3.10;
4.3.9令flag=0,表示停止存储中间表示关键指令信息,转4.3.11;
4.3.10令a=a+1,转4.3.6;
4.3.11令a=a+1,若a小于Rp的长度,转4.3.3,否则转4.3.12;
4.3.12得到关键语义表示信息队列Sp,Sp中的元素为过滤掉了无用噪音信息的Rp中的代码,转4.4;
4.4语义图构建模块采用语义图构建方法根据Sp构建语义图Gp。方法是:
4.4.1初始化语义图Gp为空,即初始化语义图Gp的节点集合Vp、数据流边集合E_datap和控制流边集合E_controlp为空;
4.4.2语义图构建模块为Gp的节点集合Vp添加变量节点,方法是:
4.4.2.1初始化变量k=1;
4.4.2.2判断Sp第k个元素
Figure BDA0003617008140000163
是否为变量声明语句,若是变量声明语句,转4.4.2.3向Vp中添加变量节点;否则转4.4.2.4;
4.4.2.3利用正则表达式从
Figure BDA0003617008140000164
中提取变量var以及var的类型type,根据变量var以及var的类型type,以三元组的形式构建变量节点(var,type,vvar),vvar是变量节点的标识,表示此节点的类型为变量节点,vvar中存储的值为var,其数据类型为type,将变量节点(var,type,vvar)加入Vp中;
4.4.2.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,转到4.4.3;否则转4.4.2.2;
4.4.3语义图构建模块为Gp的节点集合Vp添加语句块节点,方法是:
4.4.3.1初始化变量k=1;
4.4.3.2判断Sp第k个元素
Figure BDA0003617008140000165
是否为语句块声明语句,即判断
Figure BDA0003617008140000166
中是否包含关键词“label%”,若包含“label%”,转4.4.3.3向Vp中添加语句块节点;否则转4.4.3.4;
4.4.3.3利用正则表达式从
Figure BDA0003617008140000167
中提取语句块标识符marker,根据标识符marker,以二元组的形式构建语句块标识符节点(marker,vcontrol),vcontrol是语句块标识符节点的标识,表示此节点类型为语句块标识符节点,其中存储的值为marker,将语句块标识符节点(marker,vcontrol)加入Vp中;
4.4.3.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,转到4.4.4;否则转4.4.3.2;
4.4.4语义图构建模块为语义图Gp添加操作符节点、数据流边和控制流边,操作符节点包括函数调用节点、运算符节点、取值操作符节点,方法是:
4.4.4.1初始化变量k=1;
4.4.4.2初始化变量u=1;
4.4.4.3判断Sp中第k个元素
Figure BDA0003617008140000171
是否为语句块声明语句,即是否包含关键词“label%”,若是语句块声明语句,转4.4.4.4提取当前语句块的语句块标识符节点;否则转4.4.4.5;
4.4.4.4利用正则表达式从
Figure BDA0003617008140000172
中提取语句块标识符marker,对变量u赋值,使u=marker,说明当前的中间表示语句属于语句块标识符节点(u,vcontrol)所代表的语句块,vcontrol表示此节点类型为语句块标识符节点,vcontrol中存储的值为u;
4.4.4.5判断
Figure BDA0003617008140000173
是否为函数调用语句,即判断
Figure BDA0003617008140000174
是否包含“invoke”关键词,若包含“invoke”,转4.4.4.6向Gp的节点集合Vp中添加函数调用节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.6使用正则表达式从
Figure BDA0003617008140000175
中提取调用函数的函数名method、函数调用的输入变量varin、函数的返回值变量varreturn。根据函数名method,以二元组的形式构建函数调用节点(method,vinvoke),vinvoke是构建函数调用节点的标识,表示此节点类型为函数调用节点,vinvoke中存储的值为method,将函数调用节点(method,vinvoke)加入Vp中。在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(method,vinvoke),econtrol-flow),表示函数调用节点(method,vinvoke)属于语句块标识符节点(u,vcontrol)所代表的语句块,econtrol-flow表示添加的边的属性为控制流边。在Gp的数据流边集合E_datap中以三元组形式添加两条数据流边,分别为((varin,type,vvar),(method,vinvoke),edata-flow)和((method,vinvoke),(varreturn,type,vvar),edata-flow),说明数据从变量节点(varin,type,vvar)输入函数调用节点(method,vinvoke)进行函数调用计算,经过函数调用计算得到的数据从函数调用节点(method,vinvoke)输出到变量节点(varreturn,type,vvar),edata-flow表示添加的边的属性为数据流边;
4.4.4.7判断Sp中第w个元素
Figure BDA0003617008140000176
是否为数据运算语句,即是否包含关键词“/”、“%”、“+”、“-”、“*”、“cmp”中的任意一个,若是数据运算语句,转4.4.4.8向Vp中添加运算符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.8使用正则表达式从
Figure BDA0003617008140000181
中提取数据运算的运算符op、参与运算的变量varin、运算的结果变量varreturn。根据运算符op,以二元组的形式构建运算符节点(op,voperator),voperator是运算符节点的标识,表示此节点为运算符节点,voperator中存储的值为op,将运算符节点(op,voperator)加入Vp中。在Gp的控制流边集合E_contrplp中添加控制流边((u,vcontrol),(op,voperator),econtrol-flow),表示运算符节点(op,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块。在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(op,voperator),edata-flow)和((op,voperator),(varreturn,type,vvar),edata-flow),表示数据从变量节点(varin,type,vvar)输入运算符节点(op,voperator),运算后的数据从运算符节点(op,voperator)输出到变量节点(varreturn,type,vvar);
4.4.4.9判断Sp中第w个元素
Figure BDA0003617008140000182
是否为数组取值语句,即是否包含取值操作符“getelem”,若
Figure BDA0003617008140000183
包含关键词“getelem”,转4.4.4.10向Gp中添加操作符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.10使用正则表达式从
Figure BDA0003617008140000184
中提取数组变量varin,并提取结果变量varreturn。以二元组的形式构建取值操作符节点(getelem,voperator),表示运算符节点voperator中存储的值为取值操作符getelem,将取值操作符节点加入Vp中。在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(getelem,voperator),econtrol-flow),表示取值操作符节点(getelem,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块。在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(getelem,voperator),edata-flow),和((getelem,voperator),(varreturn,type,vvar),edata-flow),表示数组中的数据从数组变量节点(varin,type,vvar)输入取值操作符节点(getelem,voperator),经过取值操作从数组变量中得到的数据从取值操作符节点(getelem,voperator)输出到结果变量节点(varreturn,type,vvar);
4.4.4.11判断Sp中第w个元素
Figure BDA0003617008140000185
是否为判断语句或跳转语句,即是否包含关键词“goto”或“if”,若
Figure BDA0003617008140000186
包含关键词“goto”或“if”,转4.4.4.12向Gp中添加控制流边;否则转4.4.4.15;
4.4.4.12使用正则表达式从
Figure BDA0003617008140000187
中提取判断语句或跳转语句的目标语句块节点标识符newmarker。在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(newmarker,vcontrol),econtrol-flowr),表示程序执行时将从当前语句块标识符节点(u,vcontrol)所代表的语句块跳转到语句块标识符节点(newmarker,vcontrol)所代表的语句块。
4.4.4.13判断Sp中第w个元素
Figure BDA0003617008140000188
是否为赋值语句或类型转换语句,即是否包含关键词“=”,若
Figure BDA0003617008140000191
包含关键词“=”,转4.4.4.14向Gp中添加数据流边;否则转4.4.4.15;
4.4.4.14使用正则表达式从
Figure BDA0003617008140000192
中提取输入变量varin以及输出变量varreturn。在Gp的数据流边集合E_datap中以三元组的形式添加数据流边((varin,type,vvar),(varreturn,type,vvar),edata-flow),说明数据从变量varin输出到变量varreturn中。
4.4.4.15令k=k+1,若k大于Sp的长度,说明得到Gp,将Gp加入语义图集合SG中,转4.5;否则,转到4.4.4.3;
4.5若p大于代码中间表示数据集IR的大小,则得到语义图集合SG,转第五步;否则令p=p+1,转4.3;
第五步,根据语义图集合SG制作代码向量生成模块所需的训练数据集。方法为:
5.1令变量i=1;
5.2初始化训练数据集TrainingSet={};
5.3随机从语义图集合SG中任意抽取两个语义图,令第i次抽取的语义图为
Figure BDA0003617008140000193
Figure BDA0003617008140000194
Figure BDA0003617008140000195
Figure BDA0003617008140000196
所对应的代码功能相同,则标注Labeli为True,表示
Figure BDA0003617008140000197
Figure BDA0003617008140000198
所对应的代码为克隆代码;否则标注Labeli为False,表示
Figure BDA0003617008140000199
Figure BDA00036170081400001910
所对应的代码不为克隆代码;令第i个三元组
Figure BDA00036170081400001911
将Di放入训练数据集TrainingSet,转5.4;
5.4令i=i+1,若i>10,000,则训练集制作完成,将训练数据集TrainingSet发送到代码向量生成模块,转第六步;否则转5.3;
第六步:采用TrainingSet训练代码向量生成模块,得到可以表示语义图信息的图匹配网络。具体方法是:
6.1设置训练图匹配网络所需参数。方法是:
6.1.1设置图匹配网络包含网络层数T=4;
6.1.2设置图匹配网络学习率ir=0.001;
6.1.3设置训练轮数num_epochs=50;
6.1.4初始化训练轮数epochs=0;
6.2令变量i=1;
6.3从训练数据集TrainingSet中抽取第i个数据Di
Figure BDA00036170081400001912
6.4采用第一初始化方法初始化
Figure BDA00036170081400001913
中节点的向量值与边的权重值,得到初始化后的第一语义图
Figure BDA00036170081400001914
方法如下:
6.4.1使用Word2vec模型初始化
Figure BDA0003617008140000201
中节点的向量值:从
Figure BDA0003617008140000202
的节点集合Vi 1中顺序选择节点x,x∈Vi 1,将节点x中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点x的初始化向量
Figure BDA0003617008140000203
6.4.2令
Figure BDA0003617008140000204
的数据流边集合
Figure BDA0003617008140000205
中每条边的权重值为1;
6.4.3令
Figure BDA0003617008140000206
的控制流边集合
Figure BDA0003617008140000207
中每条边的权重值为-1;
6.5采用第二初始化方法初始化
Figure BDA0003617008140000208
中节点的向量值与边的权重值,得到初始化后的第二语义图
Figure BDA0003617008140000209
6.5.1使用Word2vec模型初始化
Figure BDA00036170081400002010
中节点的向量值,从
Figure BDA00036170081400002011
的节点集合Vi 2中顺序选择节点z,z∈Vi 2,将节点z中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点z的初始化向量
Figure BDA00036170081400002012
6.5.2令
Figure BDA00036170081400002013
的数据流边集合
Figure BDA00036170081400002014
中每条边的权重值为1;
6.5.3令
Figure BDA00036170081400002015
的控制流边集合
Figure BDA00036170081400002016
中每条边的权重值为-1;
6.6采用迭代更新方法更新第一语义图
Figure BDA00036170081400002017
中各节点的向量表示,得到第一最终语义图
Figure BDA00036170081400002018
迭代更新方法如下:
6.6.1初始化变量t=1;
6.6.2从
Figure BDA00036170081400002019
的节点集合Vi 1中顺序选择第一节点x,x∈Vi 1,若
Figure BDA00036170081400002032
的节点集合Vi 1中所有节点都已被选择,则转6.6.7;否则转6.6.3;
6.6.3计算在第t次迭代时,
Figure BDA00036170081400002020
中的节点与
Figure BDA00036170081400002021
的相似性,方法是:
6.6.3.1从
Figure BDA00036170081400002022
的节点集合Vi 2中顺序选择第二节点,令第二节点为z,z∈Vi 2,若
Figure BDA00036170081400002023
的节点集合Vi 2中所有节点都已被选择,则转6.6.3.3;否则转6.6.3.2;
6.6.3.2计算x与z的相似度αz→x
Figure BDA00036170081400002024
其中
Figure BDA00036170081400002025
指x在t-1次迭代后的向量表示,
Figure BDA00036170081400002026
指z在t-1次迭代后的向量表示,
Figure BDA00036170081400002027
Figure BDA00036170081400002028
中任意一个不是z的节点在t-1次迭代后的向量表示,转到6.6.3.1;
6.6.3.3计算在第t次迭代时x与
Figure BDA00036170081400002029
的节点集合Vi 2中所有节点的相似度和
Figure BDA00036170081400002030
Figure BDA00036170081400002031
6.6.4计算在第t次迭代时,第一语义图
Figure BDA00036170081400002033
中与x有边相连的其他节点即第三节点y传递给x的消息向量和,方法是:
6.6.4.1在
Figure BDA00036170081400002034
中除x外的节点集合Vi 1-x中顺序选择第三节点,令第三节点为y,记连接x和y的边为exy,若Vi 1-x中的所有节点都已被选择,则转6.6.4.4;否则转6.6.4.2;
6.6.4.2判断边exy是否存在于
Figure BDA0003617008140000211
的数据流边集合
Figure BDA0003617008140000212
Figure BDA0003617008140000213
的控制流边集合
Figure BDA0003617008140000214
中,若存在,转6.6.4.3;否则转6.6.4.1;
6.6.4.3计算
Figure BDA0003617008140000215
中y对x的消息向量my→x
Figure BDA0003617008140000216
其中SUM为求和函数,
Figure BDA0003617008140000217
指x在t-1次迭代后的向量表示,
Figure BDA0003617008140000218
指y在t-1次迭代后的向量表示,exy指连接x和y的边的权重值,转到6.6.4.1;
6.6.4.4计算在第t次迭代时,第一语义图
Figure BDA0003617008140000219
中的x与其有边相连的所有第三节点y对x传递的消息向量和
Figure BDA00036170081400002110
Figure BDA00036170081400002111
6.6.5更新
Figure BDA00036170081400002112
中x在第t次迭代后的向量表示
Figure BDA00036170081400002113
Figure BDA00036170081400002114
其中GRU表示门控循环神经网络,表示利用门控循环神经网络,根据第t-1次迭代后x节点的向量
Figure BDA00036170081400002115
Figure BDA00036170081400002116
中与节点x相连的其他节点传递的消息向量和
Figure BDA00036170081400002117
x与
Figure BDA00036170081400002118
的节点集合Vi 2中所有节点的相似度和6.6.3.3中计算得到的
Figure BDA00036170081400002119
生成第t次迭代后的向量表示
Figure BDA00036170081400002120
6.6.6令t=t+1。若t小于T,转6.6.2;否则说明迭代更新完毕,得到第一最终语义图
Figure BDA00036170081400002121
转6.7;
6.7采用6.6所述迭代更新方法更新
Figure BDA00036170081400002122
中各节点的向量表示,得到第二最终语义图
Figure BDA00036170081400002123
6.8计算
Figure BDA00036170081400002124
的向量表示Vi 1
Figure BDA00036170081400002125
其中MLP为多层感知器模型,表示利用多层感知器模型将
Figure BDA00036170081400002128
中所有节点的向量汇总为向量Vi 1,其中
Figure BDA00036170081400002129
为经过T轮迭代后得到的最终语义图
Figure BDA00036170081400002130
中各个节点的向量值;
6.9计算
Figure BDA00036170081400002131
的向量表示Vi 2
Figure BDA00036170081400002126
6.10利用余弦相似度函数比较Vi 1,Vi 2的相似度。
Figure BDA00036170081400002127
判断SIM是否大于相似度阈值α,一般0.7≤α<1,若是,则认为
Figure BDA00036170081400002132
Figure BDA00036170081400002133
所对应的代码是克隆代码,即模型预测结果Labelpredict=True,否则
Figure BDA00036170081400002134
Figure BDA00036170081400002135
所对应的代码不为克隆代码,模型预测结果Labelpredict=False;
6.11若Labelpredict不等于Labeli,则转6.12;否则转6.15;
6.12若Labeli=False,跳转到6.13;若Labeli=True则跳转到6.14;
6.13计算模型调整值Loss=-(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.14设置向量调整值Loss=(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.15令i=i+1,若i大于语义图数据集SG的大小,说明已训练完一轮,转6.16;否则转6.3;
6.16令epochs=epochs+1,若epochs等于num_epochs,说明训练完毕,得到了可以表示语义图信息的图匹配网络,也即得到了训练后的代码向量生成模块,转第七步;否则转6.2,开始新一轮训练;
第七步:使用代码克隆系统检测用户输入的一对待检测代码C1,C2,判断C1,C2是否是克隆代码对,方法是:
7.1令待检测代码集合Test={C1,C2};
7.2代码补全模块采用第二步所述代码补全方法对待检测代码集合Test进行代码补全,得到补全后可编译的待检测代码集合Test_Data={C‘1,C‘2};
7.3代码中间表示提取模块采用第三步所述代码中间表示提取方法从对Test_Data提取代码中间表示,构建待检测代码集合的代码中间表示集合Test_IR,Test_IR={R1,R2};
7.4语义图生成模块采用第四步所述语义图集合构建方法根据Test_IR构建待检测代码集合的语义图集合Test_SG={G1,G2};
7.5训练好的代码向量生成模块根据Test_SG中的第一语义图G1和第二语义图G2,生成其对应的向量值V1和V2,方法如下;
7.5.1采用6.4所述第一初始化方法初始化G1,得到初始化后的语义图IG1,采用6.5所述第二初始化方法初始化G2得到初始化后的语义图IG2
7.5.2采用6.6所述迭代更新方法迭代更新初始化语义图IG1和IG2中节点的向量,分别得到最终语义图FG1和FG2
7.5.3计算FG1的向量值V1
Figure BDA0003617008140000221
7.5.4计算FG2的向量值V2
Figure BDA0003617008140000222
7.6训练好的向量生成模块利用余弦相似度函数比较V1和V2的相似度。
Figure BDA0003617008140000223
Figure BDA0003617008140000224
判断SIM是否大于相似度阈值α,若SIM>α,则认为G1和G2所对应的代码是克隆代码,即模型预测结果Labelpredict=True;若SIM≤α,G1和G2所对应的代码不为克隆代码,模型预测结果Labelpredict=False。
表1是本发明与其他代码克隆检测方法在BigCloneBench数据集上训练与测试结果的对比表。
克隆检测方法 准确率 召回率 F1值
CCGRAPH 0.28 0.39 0.32
TBCCD 0.31 0.37 0.35
本发明 0.58 0.44 0.50
表1
所有实验基于一台Ubuntu16.04操作系统,搭载2080TiGPU,主要编码语言为Python。在第四步主要利用python中Networkx库实现构建语义图,第五步中从Bigclonebench数据集中抽取10,000对代码作为训练集,在训练集中,克隆代码对与非克隆代码对比例为1:1,第六步中利用Pytorch库实现图匹配网络。
为了更高的评估本发明与背景技术之间的效果,选用准确率、召回率和F1值作为评估指标。准确率为克隆检测工具报告的克隆代码对中,判断正确的比例,召回率为克隆检测工具正确判断的克隆代码对,在所有克隆对中的占比。由于相似度阈值α的调节会导致召回率和准确率无法兼顾,例如调高相似度阈值α,会导致准确率提高,召回率下降。F1指标的计算为(准确率+召回率)/2×准确率×召回率,可以综合评估准确率和召回率。
根据实验结果显示,经过12小时的模型训练,可以有效的检测到BigCloneBench中超过44%的代码克隆(即可以找出44%占比的克隆代码对),并且保证58%的准确率(即找到的克隆代码对中有58%是真正的克隆代码对),F1值为0.50。而已有最优方法TBCCD在同等实验时,只能检测到37%代码克隆,且仅能取得31%的准确度,F1值仅为0.35。另一个常用克隆检测方法CCGRAPH只能检测到39%代码克隆,且仅能取得28%的准确度,F1值仅为0.32。因此本发明相比现有方法对代码克隆的检测准确率有较大提高。

Claims (9)

1.一种基于图匹配网络的语义类代码克隆检测方法,其特征在于包含以下步骤:
第一步,构建代码克隆检测系统,代码克隆检测系统由代码补全模块、代码中间表示提取模块、语义图构建模块、代码向量生成模块和向量相似度计算器构成;
代码补全模块与代码中间表示提取模块相连,对输入的代码对C1,C2分别进行补全,得到补全后的代码对C‘1,C‘2,将C‘1,C‘2发送给代码中间表示提取模块;
代码中间表示提取模块与代码补全模块、语义图构建模块相连,将从代码补全模块接收的C‘1,C‘2分别进行编译,提取C‘1,C‘2编译过程中的代码中间表示,构成代码中间表示对R1,R2;将R1,R2发送给语义图构建模块;
语义图构建模块与代码中间表示提取模块、代码向量生成模块相连,从代码中间表示提取模块接收R1,R2,从R1,R2中提取代码的常量、变量、操作符、API、数据流和控制流信息,分别构建表示代码语义的语义图,得到语义图对G1,G2,将G1,G2发送给代码向量生成模块;
代码向量生成模块与语义图构建模块、向量相似度计算器相连,从代码向量生成模块接收G1,G2,使用图匹配网络将G1,G2分别映射为高层向量空间中的两个代码向量V1,V2,将V1,V2发送给向量相似度计算器;
向量相似度计算器与代码向量生成模块相连,计算V1,V2的向量相似度SIM,根据SIM是否超过设定的阈值来判断V1,V2所表示的代码对C1,C2是否属于语义类代码克隆;
第二步,代码补全模块采用代码补全方法对训练集中的代码进行补全:
2.1使用BigCloneBench数据集作为训练代码,从BigCloneBench数据集中所有代码对中选择N对代码以及对应的标注作为训练集,N为正整数;
2.2令可编译代码集合Data={};
2.3令变量n=1;
2.4从训练集中抽取第n个代码段CCn,判断CCn是否可编译,若CCn可编译,转2.5,否则转2.6;
2.5将CCn加入Data中,令n=n+1,转2.9;
2.6使用JCoffee-1.0工具补全CCn,得到补全后的代码CC′n,转2.7;
2.7判断CC′n是否可编译,若可编译,转2.8,否则转2.9;
2.8将CC′n加入Data中,令n=n+1,转2.9;
2.9若n≥N,令补全后的Data中数据总数M=n,将补全后的Data发送给代码中间表示提取模块,转第三步;否则转2.4;
第三步,代码中间表示提取模块从代码补全模块接收可编译代码集合Data,采用代码中间表示提取方法从Data中提取代码中间表示,构建代码中间表示集合IR,方法为:
3.1令代码中间表示集合IR={};
3.2令变量m=1;
3.3从Data中抽取第m个代码CCm,若CCm为JAVA语言代码,转3.4;若为C语言代码,则转3.5;
3.4提取JAVA代码的代码中间表示,方法为:
3.4.1使用JavaC编译代码CCm,得到二进制文件Classm
3.4.2根据二进制文件Classm,使用Soot-4.1.0工具提取代码的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.5利用LLVM-9.0工具编译代码CCm,得到代码CCm的中间表示Rm,将Rm加入IR,令m=m+1,转3.6;
3.6若m>M,将代码中间表示集合IR发送至语义图构建模块,转第四步;若m≤M,转3.3;
第四步,语义图构建模块从代码表示提取模块接收代码中间表示集合IR,采用语义图集合构建方法根据IR构建语义图集合SG,方法为:
4.1令语义图集合SG={};
4.2令变量p=0;
4.3从IR中抽取第p个代码中间表示Rp,从Rp中提取关键语义表示信息,过滤无用噪音信息,得到关键语义表示信息队列Sp,Sp中第k个元素
Figure FDA0003617008130000021
为过滤掉了无用噪音信息的Rp中的代码,k为正整数,转4.4;
4.4语义图构建模块采用语义图构建方法根据Sp构建语义图Gp,方法是:
4.4.1初始化语义图Gp为空,即初始化语义图Gp的节点集合Vp、数据流边集合E_datap和控制流边集合E_contrplp为空;
4.4.2语义图构建模块为Gp的节点集合Vp添加变量节点,变量节点(var,type,vvar)为三元组,var为从
Figure FDA0003617008130000022
中提取的变量,type为var的数据类型,vvar表示此节点类型为变量节点;
4.4.3语义图构建模块为Gp的节点集合Vp添加语句块标识符节点,语句块标识符节点(marker,vcontrol)为二元组,marker是从
Figure FDA0003617008130000031
中提取的语句块标识符,vcontrol表示此节点类型为语句块标识符节点;
4.4.4语义图构建模块为语义图Gp添加操作符节点、数据流边和控制流边:
首先查找当前语句所属的语句块标识符节点(u,vcontrol),u为节点存储的语句块标识符marker,vcontrol表示此节点类型为语句块标识符节点;
将操作符节点添加到Vp中,操作符节点包括函数调用节点、运算符节点、取值操作符节点,函数调用节点(method,vinvoke)为二元组,method为从
Figure FDA0003617008130000032
中提取的调用函数的函数名,vinvoke表示此节点类型为函数调用节点;运算符节点(op,voperator)为二元组,voperator表示此节点类型为运算符节点,其中存储的值为op;取值操作符节点(getelem,voperator)是二元组,voperator表示此节点运算符节点,其中存储的值为取值操作符getelem;当将函数调用节点(method,vinvoke)添加到Vp中时,将控制流边添加到Gp的控制流边集合E_controlp中,控制流边((u,vcontrol),(method,vinvoke),econtrol-flow)是三元组,表示函数调用节点(method,vinvoke)属于语句块标识符节点(u,vcontrol)所代表的语句块,econtrol-flow表示添加的边的属性为控制流边;在Gp的数据流边集合E_datap中添加两条数据流边,分别为((varin,type,vvar),(method,vinvoke),edata-flow)和((method,vinvoke),(varreturn,type,vvar),edata-flow),说明数据从变量节点(varin,type,vvar)输入函数调用节点(method,vinvoke)进行函数调用计算,经过函数调用计算得到的数据从函数调用节点(method,vinvoke)输出到变量节点(varreturn,type,vvar),edata-flow表示添加的边的属性为数据流边;
当将运算符节点添加到Vp中时,在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(op,voperator),econtrol-flow),表示函数运算符节点(op,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块;在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(op,voperator),edata-flow)和((op,voperator),(varreturn,type,vvar),edata-flow),表示数据从变量节点(varin,type,vvar)输入运算符节点(op,voperator),运算后的数据从运算符节点(op,voperator)输出到变量节点(varreturn,type,vvar);
当将取值操作符节点加入Vp中时,在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(getelem,voperator),econtrol-flow),表示取值操作符节点(getelem,voperator)属于语句块标识符节点(u,vcontrol)所代表的语句块;在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(getelem,voperator),edata-flow),和((getelem,voperator),(varreturn,type,vvar),edata-flow),表示数组中的数据从数组变量节点(varin,type,vvar)输入取值操作符节点(getelem,voperator),经过取值操作从数组变量中得到的数据从取值操作符节点(getelem,voperator)输出到变量节点(varreturn,type,vvar);
Figure FDA0003617008130000041
为判断语句或跳转语句时,在Gp的控制流边集合E_controlp中以三元组的形式添加控制流边((u,vcontrol),(newmarker,vcontrol),econtrol-flowr),表示程序执行时将从当前语句块标识符节点(u,vcontrol)所代表的语句块跳转到语句块标识符节点(newmarker,vcontrol)所代表的语句块;在Gp的数据流边集合E_datap中以三元组的形式添加数据流边((varin,type,vvar),(varreturn,type,vvar),edata-flow),说明数据从变量varin输出到变量varreturn中;
将Gp加入语义图集合SG中;
4.5若p大于代码中间表示数据集IR的大小,则得到语义图集合SG,转第五步;否则令p=p+1,转4.3;
第五步,根据语义图集合SG制作代码向量生成模块所需的训练数据集TrainingSet,TrainingSet中的第i个元素为三元组
Figure FDA0003617008130000042
将TrainingSet发送到代码向量生成模块;Labeli为True,表示
Figure FDA0003617008130000043
Figure FDA0003617008130000044
所对应的代码功能相同,为克隆代码;Labeli为False,表示
Figure FDA0003617008130000045
Figure FDA0003617008130000046
所对应的代码不为克隆代码;
第六步:采用TrainingSet训练代码向量生成模块,得到表示语义图信息的图匹配网络,方法是:
6.1设置训练图匹配网络所需参数;方法是:
6.1.1设置图匹配网络包含网络层数T=4;
6.1.2设置图匹配网络学习率ir=0.001;
6.1.3设置训练轮数num_epochs=50;
6.1.4初始化训练轮数epochs=0;
6.2令变量i=1;
6.3从训练数据集TrainingSet中抽取第i个数据Di
Figure FDA0003617008130000047
6.4采用第一初始化方法初始化
Figure FDA0003617008130000048
中节点的向量值与边的权重值,得到初始化后的第一语义图
Figure FDA0003617008130000049
方法如下:
6.4.1使用Word2vec模型初始化
Figure FDA00036170081300000410
中节点的向量值:从
Figure FDA00036170081300000411
的节点集合Vi 1中顺序选择节点x,x∈Vi 1,将节点x中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点x的初始化向量
Figure FDA0003617008130000051
6.4.2令
Figure FDA0003617008130000052
的数据流边集合
Figure FDA0003617008130000053
中每条边的权重值为1;
6.4.3令
Figure FDA0003617008130000054
的控制流边集合
Figure FDA0003617008130000055
中每条边的权重值为-1;
6.5采用第二初始化方法初始化
Figure FDA0003617008130000056
中节点的向量值与边的权重值,得到初始化后的第二语义图
Figure FDA0003617008130000057
方法如下:
6.5.1使用Word2vec模型初始化
Figure FDA0003617008130000058
中节点的向量值,从
Figure FDA0003617008130000059
的节点集合Vi 2中顺序选择节点z,z∈Vi 2,将节点z中存储的内容输入Word2vec模型,将Word2vec模型输出值作为节点z的初始化向量
Figure FDA00036170081300000510
6.5.2令
Figure FDA00036170081300000511
的数据流边集合
Figure FDA00036170081300000512
中每条边的权重值为1;
6.5.3令
Figure FDA00036170081300000513
的控制流边集合
Figure FDA00036170081300000514
中每条边的权重值为-1;
6.6采用迭代更新方法更新第一语义图
Figure FDA00036170081300000515
中各节点的向量表示,得到第一最终语义图
Figure FDA00036170081300000516
迭代更新方法如下:
6.6.1初始化变量t=1;
6.6.2从
Figure FDA00036170081300000517
的节点集合Vi 1中顺序选择第一节点x,若
Figure FDA00036170081300000518
的节点集合Vi 1中所有节点都已被选择,则转6.6.7;否则转6.6.3;
6.6.3计算在第t次迭代时,
Figure FDA00036170081300000519
中的节点与
Figure FDA00036170081300000520
的相似性,方法是:
6.6.3.1从
Figure FDA00036170081300000521
的节点集合Vi 2中顺序选择第二节点,令第二节点为z,若
Figure FDA00036170081300000522
的节点集合Vi 2中所有节点都已被选择,则转6.6.3.3;否则转6.6.3.2;
6.6.3.2计算x与z的相似度αz→x
Figure FDA00036170081300000523
其中
Figure FDA00036170081300000524
指x在t-1次迭代后的向量表示,
Figure FDA00036170081300000525
指z在t-1次迭代后的向量表示,
Figure FDA00036170081300000526
Figure FDA00036170081300000527
中任意一个不是z的节点在t-1次迭代后的向量表示,转到6.6.3.1;
6.6.3.3计算在第t次迭代时x与
Figure FDA00036170081300000528
的节点集合Vi 2中所有节点的相似度和
Figure FDA00036170081300000529
Figure FDA00036170081300000530
6.6.4计算在第t次迭代时,第一语义图
Figure FDA00036170081300000531
中与x有边相连的其它节点即所有第三节点y传递给x的消息向量和
Figure FDA00036170081300000532
my→x
Figure FDA00036170081300000533
中y对x的消息向量;
6.6.5更新
Figure FDA00036170081300000534
中x在第t次迭代后的向量表示
Figure FDA00036170081300000535
其中GRU表示门控循环神经网络,表示利用门控循环神经网络根据第t-1次迭代后x节点的向量
Figure FDA00036170081300000536
生成第t次迭代后的向量表示
Figure FDA00036170081300000537
6.6.6令t=t+1;若t小于T,转6.6.2;否则说明迭代更新完毕,得到第一最终语义图
Figure FDA0003617008130000061
转6.7;
6.7采用6.6所述迭代更新方法更新
Figure FDA0003617008130000062
中各节点的向量表示,得到第二最终语义图
Figure FDA0003617008130000063
6.8计算
Figure FDA0003617008130000064
的向量表示
Figure FDA0003617008130000065
其中MLP为多层感知器模型,表示利用多层感知器模型将
Figure FDA0003617008130000066
中所有节点的向量汇总为向量Vi 1,其中
Figure FDA0003617008130000067
为经过T轮迭代后得到的最终语义图
Figure FDA0003617008130000068
中各个节点的向量值;
6.9计算
Figure FDA0003617008130000069
的向量表示Vi 2
Figure FDA00036170081300000610
6.10利用余弦相似度函数比较Vi 1,Vi 2的相似度;
Figure FDA00036170081300000611
判断SIM是否大于相似度阈值α,若是,则认为
Figure FDA00036170081300000612
Figure FDA00036170081300000613
所对应的代码是克隆代码,即模型预测结果Labelpredict=True,否则
Figure FDA00036170081300000614
Figure FDA00036170081300000615
所对应的代码不为克隆代码,模型预测结果Labelpredict=False;
6.11若Labelpredict不等于Labeli,则转6.12;否则转6.15;
6.12若Labeli=False,跳转到6.13;若Labeli=True则跳转到6.14;
6.13计算模型调整值Loss=-(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.14设置向量调整值Loss=(1-SIM)×ir,将Loss输入word2vec模型,word2vec模型自动更新模型中的参数,转6.15;
6.15令i=i+1,若i大于语义图数据集SG的大小,说明已训练完一轮,转6.16;否则转6.3;
6.16令epochs=epochs+1,若epochs等于num_epochs,说明训练完毕,得到了图匹配网络,也即得到了训练后的代码向量生成模块,转第七步;否则转6.2,开始新一轮训练;
第七步:使用代码克隆系统检测用户输入的一对待检测代码C1,C2,判断C1,C2是否是克隆代码对,方法是:
7.1令待检测代码集合Test={C1,C2};
7.2代码补全模块采用第二步所述代码补全方法对待检测代码集合Test进行代码补全,得到补全后可编译的待检测代码集合Test_Data={C‘1,C‘2};
7.3代码中间表示提取模块采用第三步所述代码中间表示提取方法从对Test_Data 提取代码中间表示,构建待检测代码集合的代码中间表示集合Test_IR,Test_IR={R1,R2};
7.4语义图生成模块采用第四步所述语义图集合构建方法根据Test_IR构建待检测代码集合的语义图集合Test_SG={G1,G2};
7.5训练好的代码向量生成模块根据Test_SG中的第一语义图G1和第二语义图G2,生成其对应的向量值V1和V2,方法如下;
7.5.1采用6.4所述第一初始化方法初始化G1,得到初始化后的语义图IG1,采用6.5所述第二初始化方法初始化G2得到初始化后的语义图IG2
7.5.2采用6.6所述迭代更新方法迭代更新初始化语义图IG1和IG2中节点的向量,分别得到最终语义图FG1和FG2
7.5.3计算FG1的向量值V1
Figure FDA0003617008130000071
7.5.4计算FG2的向量值V2
Figure FDA0003617008130000072
7.6训练好的向量生成模块利用余弦相似度函数比较V1和V2的相似度;
Figure FDA0003617008130000073
Figure FDA0003617008130000074
判断SIM是否大于相似度阈值α,若SIM>α,则认为G1和G2所对应的代码是克隆代码,即模型预测结果Labelpredict=True;若SIM≤α,G1和G2所对应的代码不为克隆代码,模型预测结果Labelpredict=False。
2.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于2.1步所述N满足80299521≥N≥10,000。
3.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于4.3步所述从Rp中提取关键语义表示信息,过滤无用噪音信息的方法是:
4.3.1初始化关键语义表示信息队列Sp为空;
4.3.2初始化变量a=1,初始化标识flag=0;
4.3.3判断Rp的第a行代码
Figure FDA0003617008130000075
是否包含函数名,若包含函数名,说明此时已检索到代码中间表示关键指令信息起始位置,转到4.3.5,否则转到4.3.4;
4.3.4令a=a+1,若a≤Rp的长度,转4.3.3;若a>Rp的长度,转4.3.12;
4.3.5将
Figure FDA0003617008130000076
加入到Sp中,令a=a+1;
4.3.6若
Figure FDA0003617008130000077
包含符号“{”,说明
Figure FDA0003617008130000078
为中间表示语句块的开始位置,转4.3.7;若
Figure FDA0003617008130000079
包含符号“}”,说明
Figure FDA00036170081300000710
为中间表示语句块的结束位置,转4.3.9;若
Figure FDA00036170081300000711
既不包含“{”,也不包含“}”,说明
Figure FDA00036170081300000712
为中间表示语句块的中间位置,转4.3.8;
4.3.7令flag=1,表示开始存储中间表示关键指令信息,转4.3.10;
4.3.8若flag=1,将
Figure FDA0003617008130000081
加入到Sp中,转4.3.10;
4.3.9令flag=0,表示停止存储中间表示关键指令信息,转4.3.11;
4.3.10令a=a+1,转4.3.6;
4.3.11令a=a+1,若a小于Rp的长度,转4.3.3,否则转4.3.12;
4.3.12得到关键语义表示信息队列Sp
4.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于4.4.2步所述语义图构建模块为Vp添加变量节点的方法是:
4.4.2.1初始化变量k=1;
4.4.2.2判断Sp第k个元素
Figure FDA0003617008130000082
是否为变量声明语句,若是变量声明语句,转4.4.2.3向Vp中添加变量节点;否则转4.4.2.4;
4.4.2.3利用正则表达式从
Figure FDA0003617008130000083
中提取变量var以及var的类型type,根据变量var以及var的类型type,以三元组的形式构建变量节点(var,type,vvar),vvar是变量节点的标识,表示此节点的类型为变量节点,vvar中存储的值为var,var数据类型为type,将变量节点(var,type,vvar)加入Vp中;
4.4.2.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到Vp中,结束;否则转4.4.2.2。
5.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于4.4.3步所述语义图构建模块为Gp添加语句块标识符节点,方法是:
4.4.3.1初始化变量k=1;
4.4.3.2判断Sp第k个元素
Figure FDA0003617008130000084
是否为语句块声明语句,即判断
Figure FDA0003617008130000085
中是否包含关键词“label%”,若包含“label%”,转4.4.3.3向Vp中添加语句块节点;否则转4.4.3.4;
4.4.3.3利用正则表达式从
Figure FDA0003617008130000086
中提取语句块标识符marker,根据标识符marker,以二元组的形式构建语句块标识符节点(marker,vcontrol),vcontrol是语句块标识符节点的标识,表示此节点类型为语句块标识符节点,vcontrol中存储的值为marker,将语句块标识符节点(marker,vcontrol)加入Vp中;
4.4.3.4令k=k+1,若k大于Sp的长度,说明已经将所有变量节点加入到语义图Vp中,结束;否则转4.4.3.2。
6.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于4.4.4步所述语义图构建模块为语义图Gp添加操作符节点、数据流边和控制流边的方法是:
4.4.4.1初始化变量k=1;
4.4.4.2初始化变量u=1;
4.4.4.3判断Sp中第k个元素
Figure FDA0003617008130000091
是否为语句块声明语句,即是否包含关键词“label%”,若是语句块声明语句,转4.4.4.4提取当前语句块的语句块标识符节点;否则转4.4.4.5;
4.4.4.4利用正则表达式从
Figure FDA0003617008130000092
中提取语句块标识符marker,对变量u赋值,使u=marker,说明当前的中间表示语句属于语句块标识符节点(u,vcontrol)所代表的语句块,vcontrol表示此节点类型为语句块标识符节点,vcontrol中存储的值为u;
4.4.4.5判断
Figure FDA0003617008130000093
是否为函数调用语句,即判断
Figure FDA0003617008130000094
是否包含“invoke”关键词,若包含“invoke”,转4.4.4.6向Gp的节点集合Vp中添加函数调用节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.6使用正则表达式从
Figure FDA0003617008130000095
中提取调用函数的函数名method、函数调用的输入变量varin、函数的返回值变量varreturn;根据函数名method,以二元组的形式构建函数调用节点(method,vinvoke),vinvoke是构建函数调用节点的标识,表示此节点类型为函数调用节点,vinvoke中存储的值为method,将函数调用节点(method,vinvoke)加入Vp中;在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(method,vinvoke),econtrol-flow);在Gp的数据流边集合E_datap中添加两条数据流边,分别为((varin,type,vvar),(method,vinvoke),edata-flow)和((method,vinvoke),(varreturn,type,vvar),edata-flow);
4.4.4.7判断Sp中第w个元素
Figure FDA0003617008130000096
是否为数据运算语句,即是否包含关键词“/”、“%”、“+”、“-”、“*”、“cmp”中的任意一个,若是数据运算语句,转4.4.4.8向Gp中添加运算符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.8使用正则表达式从
Figure FDA0003617008130000097
中提取数据运算的运算符op、参与运算的变量varin、运算的结果变量varreturn;根据运算符op,以二元组的形式构建运算符节点(op,voperator),voperator是运算符节点的标识,表示此节点为运算符节点,voperator中存储的值为op,将运算符节点(op,voperator)加入Vp中;在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(op,voperator),econtrol-flow);在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(op,voperator),edata-flow)和((op,voperator),(varreturn,type,vvar),edata-flow);
4.4.4.9判断Sp中第w个元素
Figure FDA0003617008130000101
是否为数组取值语句,即是否包含取值操作符“getelem”,若
Figure FDA0003617008130000102
包含关键词“getelem”,转4.4.4.10向Gp中添加操作符节点,并添加对应的数据流和控制流边;否则转4.4.4.15;
4.4.4.10使用正则表达式从
Figure FDA0003617008130000103
中提取数组变量varin,并提取结果变量varreturn;以二元组的形式构建取值操作符节点(getelem,voperator),将取值操作符节点加入Vp中;在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(getelem,voperator),econtrol-flow);在Gp的数据流边集合E_datap中以三元组的形式添加两条数据流边,即((varin,type,vvar),(getelem,voperator),edata-flow),和((getelem,voperator),(varreturn,type,vvar),edata-flow);
4.4.4.11判断Sp中第w个元素
Figure FDA0003617008130000104
是否为判断语句或跳转语句,即是否包含关键词“goto”或“if”,若
Figure FDA0003617008130000105
包含关键词“goto”或“if”,转4.4.4.12向Gp中添加控制流边;否则转4.4.4.15;
4.4.4.12使用正则表达式从
Figure FDA0003617008130000106
中提取判断语句或跳转语句的目标语句块节点标识符newmarker;在Gp的控制流边集合E_controlp中添加控制流边((u,vcontrol),(newmarker,vcontrol),econtrol-flowr);
4.4.4.13判断Sp中第w个元素
Figure FDA0003617008130000107
是否为赋值语句或类型转换语句,即是否包含关键词“=”,若
Figure FDA0003617008130000108
包含关键词“=”,转4.4.4.14向Gp中添加数据流边;否则转4.4.4.15;
4.4.4.14使用正则表达式从
Figure FDA0003617008130000109
中提取输入变量varin以及输出变量varreturn;在Gp的数据流边集合E_datap中添加数据流边((varin,type,vvar),(varreturn,type,vvar),edata-flow);
4.4.4.15令k=k+1,若k大于Sp的长度,说明得到Gp,将Gp加入语义图集合SG中,结束;否则,转到4.4.4.3。
7.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于第五步所述根据语义图集合SG制作代码向量生成模块所需的训练数据集的方法为:
5.1令变量i=1;
5.2初始化训练数据集TrainingSet={};
5.3随机从语义图集合SG中任意抽取两个语义图,令第i次抽取的语义图为
Figure FDA00036170081300001010
Figure FDA00036170081300001011
Figure FDA00036170081300001012
Figure FDA00036170081300001013
所对应的代码功能相同,则标注Labeli为True,否则标注Labeli为False;令第i个三元组
Figure FDA00036170081300001014
将Di放入训练数据集TrainingSet,转5.4;
5.4令i=i+1,若i>10,000,则训练数据集制作完成;否则转5.3。
8.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于6.6.4步所述计算在第t次迭代时,第一语义图
Figure FDA0003617008130000111
中与x有边相连的其他节点传递给x的消息向量的方法是:
6.6.4.1在
Figure FDA0003617008130000112
中除x外的节点集合Vi 1-x中顺序选择第三节点,令第三节点为y,记连接x和y的边为exy,若Vi 1-x中的所有节点都已被选择,则转6.6.4.4;否则转6.6.4.2;
6.6.4.2判断边exy是否存在于
Figure FDA0003617008130000113
的数据流边集合
Figure FDA0003617008130000114
Figure FDA0003617008130000115
的控制流边集合
Figure FDA0003617008130000116
中,若存在,转6.6.4.3;否则转6.6.4.1;
6.6.4.3计算
Figure FDA0003617008130000117
中y对x的消息向量my→x
Figure FDA0003617008130000118
其中SUM为求和函数,
Figure FDA0003617008130000119
指x在t-1次迭代后的向量表示,
Figure FDA00036170081300001110
指y在t-1次迭代后的向量表示,exy指连接x和y的边的权重值,转到6.6.4.1;
6.6.4.4计算在第t次迭代时,第一语义图
Figure FDA00036170081300001111
中的x与其有边相连的所有第三节点y对x传递的消息向量和
Figure FDA00036170081300001112
9.如权利要求1所述的一种基于图匹配网络的语义类代码克隆检测方法,其特征在于所述相似度阈值α满足0.7≤α<1。
CN202210450356.XA 2022-04-26 2022-04-26 一种基于图匹配网络的语义类代码克隆检测方法 Active CN114780103B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202210450356.XA CN114780103B (zh) 2022-04-26 2022-04-26 一种基于图匹配网络的语义类代码克隆检测方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202210450356.XA CN114780103B (zh) 2022-04-26 2022-04-26 一种基于图匹配网络的语义类代码克隆检测方法

Publications (2)

Publication Number Publication Date
CN114780103A CN114780103A (zh) 2022-07-22
CN114780103B true CN114780103B (zh) 2022-12-20

Family

ID=82432774

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202210450356.XA Active CN114780103B (zh) 2022-04-26 2022-04-26 一种基于图匹配网络的语义类代码克隆检测方法

Country Status (1)

Country Link
CN (1) CN114780103B (zh)

Families Citing this family (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN117034273A (zh) * 2023-08-28 2023-11-10 山东省计算中心(国家超级计算济南中心) 基于图卷积网络的安卓恶意软件检测方法及系统

Citations (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN112215013A (zh) * 2020-11-02 2021-01-12 天津大学 一种基于深度学习的克隆代码语义检测方法
CN112286575A (zh) * 2020-10-20 2021-01-29 杭州云象网络技术有限公司 基于图匹配模型的智能合约相似度检测方法及系统
KR20210098297A (ko) * 2020-01-31 2021-08-10 고려대학교 산학협력단 바이너리 코드 클론 기반 소프트웨어 취약점 탐지를 위한 컴퓨터 프로그램
CN113961241A (zh) * 2021-11-02 2022-01-21 南京大学 一种基于gat图神经网络模型的代码克隆检测方法
CN113986345A (zh) * 2021-11-01 2022-01-28 天津大学 一种预训练增强的代码克隆检测方法
CN114035843A (zh) * 2021-10-09 2022-02-11 北京天融信网络安全技术有限公司 基于Seq2Seq模型的代码克隆检测方法及检测装置
CN114064117A (zh) * 2021-11-19 2022-02-18 重庆邮电大学 一种基于字节码和神经网络的代码克隆检测方法及系统
CN114138330A (zh) * 2021-12-07 2022-03-04 中国人民解放军国防科技大学 基于知识图谱的代码克隆检测优化方法、装置和电子设备

Patent Citations (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
KR20210098297A (ko) * 2020-01-31 2021-08-10 고려대학교 산학협력단 바이너리 코드 클론 기반 소프트웨어 취약점 탐지를 위한 컴퓨터 프로그램
CN112286575A (zh) * 2020-10-20 2021-01-29 杭州云象网络技术有限公司 基于图匹配模型的智能合约相似度检测方法及系统
CN112215013A (zh) * 2020-11-02 2021-01-12 天津大学 一种基于深度学习的克隆代码语义检测方法
CN114035843A (zh) * 2021-10-09 2022-02-11 北京天融信网络安全技术有限公司 基于Seq2Seq模型的代码克隆检测方法及检测装置
CN113986345A (zh) * 2021-11-01 2022-01-28 天津大学 一种预训练增强的代码克隆检测方法
CN113961241A (zh) * 2021-11-02 2022-01-21 南京大学 一种基于gat图神经网络模型的代码克隆检测方法
CN114064117A (zh) * 2021-11-19 2022-02-18 重庆邮电大学 一种基于字节码和神经网络的代码克隆检测方法及系统
CN114138330A (zh) * 2021-12-07 2022-03-04 中国人民解放军国防科技大学 基于知识图谱的代码克隆检测优化方法、装置和电子设备

Non-Patent Citations (3)

* Cited by examiner, † Cited by third party
Title
Neural Detection of Semantic Code Clones Via Tree-Based Convolution;Hao Yu;《2019 IEEE/ACM 27th International Conference on Program Comprehension (ICPC)》;20190829;全文 *
基于差异代码克隆搜索的代码块补全推荐算法研究;殷康麒;《中国科学技术大学硕士学位论文》;20190815;全文 *
语义级代码克隆检测数据集的评估与改进;华为云开发者联盟;《https://www.cnblogs.com/huaweiyun/p/15881973.html》;20220211;全文 *

Also Published As

Publication number Publication date
CN114780103A (zh) 2022-07-22

Similar Documents

Publication Publication Date Title
CN111639344B (zh) 一种基于神经网络的漏洞检测方法及装置
Huang et al. Gamepad: A learning environment for theorem proving
Allamanis et al. Learning to represent programs with graphs
CN113360915B (zh) 基于源代码图表示学习的智能合约多漏洞检测方法及系统
Li et al. Gated graph sequence neural networks
CN112541180B (zh) 一种基于语法特征和语义特征的软件安全漏洞检测方法
CN112215013B (zh) 一种基于深度学习的克隆代码语义检测方法
CN112364352B (zh) 可解释性的软件漏洞检测与推荐方法及系统
CN110990058B (zh) 软件相似性度量方法及装置
Saifullah et al. Learning from examples to find fully qualified names of api elements in code snippets
CN111767547A (zh) 一种基于复杂网络社团的软件漏洞检测方法
CN114780103B (zh) 一种基于图匹配网络的语义类代码克隆检测方法
Lu et al. Program classification using gated graph attention neural network for online programming service
Cusumano-Towner et al. Automating involutive MCMC using probabilistic and differentiable programming
CN111045670B (zh) 一种二进制代码与源代码间复用关系的识别方法与装置
CN110737469B (zh) 一种功能粒度上基于语义信息的源代码相似度评估方法
CN115617395A (zh) 一种融合全局和局部特征的智能合约相似性检测方法
Schwier et al. Zero knowledge hidden markov model inference
CN114254323A (zh) 基于PCODE和Bert的软件脆弱性分析方法及系统
CN115373737B (zh) 一种基于特征融合的代码克隆检测方法
CN116663018A (zh) 一种基于代码可执行路径的漏洞检测方法及装置
Cummins et al. Deep data flow analysis
CN113076089B (zh) 一种基于对象类型的api补全方法
CN116361788A (zh) 一种基于机器学习的二进制软件漏洞预测方法
CN116628695A (zh) 基于多任务学习的漏洞挖掘方法及装置

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant