代码相似度的检测方法及装置、存储介质、电子设备与流程

文档序号:26007465发布日期:2021-07-23 21:26阅读:156来源:国知局
代码相似度的检测方法及装置、存储介质、电子设备与流程

本申请涉及计算机领域,尤其涉及一种代码相似度的检测方法及装置、存储介质、电子设备。



背景技术:

相关技术中,重复代码的维护需要非常高的人力成本(一个地方的修改无法同步到所有),所以公共代码的提取和抽象化是开发中的重中之重。

相关技术中采用逐行扫描方式进行代码对比,对比每行每列的文本字符是否一致,是基于字符的对比,容易被干扰,比如:代码混淆编译、特殊字符、代码逻辑一致仅变量命名不一致的代码块等。相关技术中基于字符的对比方式,并不关注代码逻辑的重复程度,只针对每行每列中字符的对比,而当代码经过编译或者混淆处理以后,变量名字符、变量定义位置、运算字符甚至运算方式可能已经发生改变,这个时候仅通过字符对比会产生非常大的误差,不能反映代码的真实情况。

针对相关技术中存在的上述问题,目前尚未发现有效的解决方案。



技术实现要素:

为了解决上述技术问题或者至少部分地解决上述技术问题,本申请提供了一种代码相似度的检测方法及装置、存储介质、电子设备。

根据本申请实施例的一个方面,提供了一种代码相似度的检测方法,包括:解析目标代码文件的语法结构,生成所述目标代码文件的抽象语法树,其中,所述抽象语法树包括若干个节点,每个所述节点对应一个临时数组和一个计数数组;采用所述临时数组和所述计数数组计算所述目标代码文件中代码块的代码相似度。

根据本申请实施例的另一个方面,还提供了一种代码相似度的检测装置,包括:生成模块,用于解析目标代码文件的语法结构,生成所述目标代码文件的抽象语法树,其中,所述抽象语法树包括若干个节点,每个所述节点对应一个临时数组和一个计数数组;计算模块,用于采用所述临时数组和所述计数数组计算所述目标代码文件中代码块的代码相似度。

进一步,所述计算模块包括:生成单元,用于基于所述ast中的多个临时数组对应生成多个计数数组,其中,所述计数数组包括变量定义表达式的以下信息:运算类型,变量类型,变量数量;对比单元,用于对比所述多个计数数组中的第一计数数组和第二计数数组,并将所述第一计数数组和所述第二计数数组之间的相似度确定为所述目标代码文件中第一代码块和第二代码块的相似度,其中,所述第一计数数组对应所述第一代码块,所述第二计数数组对应所述第二代码块。

进一步,所述生成单元包括:第一读取子单元,用于针对所述ast中的每个临时数组,读取所述临时数组中的第一关键字符,其中,所述第一关键字符用于表征变量定义表达式的运算类型;第二读取子单元,用于读取所述临时数组中的第二关键字符,并统计所述第二关键字符的变量数量,其中,所述第二关键字符用于表征当前运算类型下的变量类型,每个第二关键字符对应一个变量类型;生成子单元,用于采用所述第一关键字符、所述第二关键字符、所述变量数量生成计数数组。

进一步,所述对比单元包括:对比子单元,用于对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;第一计算子单元,用于若所述第一运算类型和所述第二运算类型相同,计算所述第一计数数组的第一变量数量与所述第二计数数组的第二变量数量之间的第一商值,其中,所述第一商值用于表征所述第一计数数组和所述第二计数数组之间的第一相似度;第一确定子单元,用于将所述第一商值,确定为所述目标代码文件中第一代码块和第二代码块之间的相似度。

进一步,所述对比单元包括:对比子单元,用于对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;第二计算子单元,用于若所述第一运算类型和所述第二运算类型相同,计算所述第一计数数组的第一变量类型数量与所述第二计数数组的第二变量类型数量之间的第二商值,所述第一变量类型数量和第二变量类型数量分别是根据所述第一运算类型和所述第二运算类型包括的变量类型种类统计得到的,其中,所述第二商值用于表征所述第一计数数组和所述第二计数数组之间的第二相似度;第二确定子单元,用于将所述第二商值,确定为所述目标代码文件中第一代码块和第二代码块之间的相似度。

进一步,所述对比单元包括:对比子单元,用于对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;第三计算子单元,用于若所述第一运算类型和所述第二运算类型相同,确定所述第一计数数组和所述第二计数数组中相同变量类型的特定变量数量,以及确定所述第一计数数组或所述第二计数数组的变量总数量,计算所述特定变量数量与所述变量总数量的第三商值,其中,所述第一计数数组和所述第二计数数组的变量总数量相同,所述第三商值用于表征所述第一计数数组和所述第二计数数组之间的第三相似度;第三确定子单元,用于将所述第三商值,确定为所述目标代码文件中第一代码块和第二代码块的相似度。

进一步,所述生成模块包括:分割单元,用于将所述目标代码文件中的代码字符串分割为词法单元,其中,每个词法单元对应一个代码块;生成单元,用于基于分割后的多个词法单元生成词法单元列表;转换单元,用于以变量定义表达式为单位将所述词法单元列表转换为ast。

进一步,所述转换单元包括:拆分子单元,用于以变量定义表达式为单位将所述词法单元列表拆分为多个临时数组,其中,每个临时数组对应一个变量定义表达式,每个变量定义表达式采用关键字符进行标识;映射子单元,用于针对所述词法单元列表的每个变量定义表达式,将对应的临时数组映射为一个子ast;组合子单元,用于将多个子ast分别确定为指定树根节点下的子节点,组合得到一个总ast。

进一步,所述分割单元包括:扫描子单元,用于从所述目标代码文件中的代码字符串的第一个字符开始,从左向右扫描所述代码字符串,直到下一个空字符串,提取空字符串之前的连续字符串;确定子单元,用于将所述连续字符串确定为关键字符,继续从左向右扫描所述代码字符串,直到所述关键字符之后最近一个标识符,将所述关键字符到所述标识符之间的字符集确定为一个词法单元;处理子单元,用于换行继续从左向右扫描剩下的所述代码字符串,直到扫描至所述代码字符串的最后一个字符。

根据本申请实施例的另一方面,还提供了一种存储介质,该存储介质包括存储的程序,程序运行时执行上述的步骤。

根据本申请实施例的另一方面,还提供了一种电子设备,包括处理器、通信接口、存储器和通信总线,其中,处理器,通信接口,存储器通过通信总线完成相互间的通信;其中:存储器,用于存放计算机程序;处理器,用于通过运行存储器上所存放的程序来执行上述方法中的步骤。

根据本申请的一个方面,提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备执行上述代码相似度的检测方法中任一实施例的步骤。

本申请实施例提供的上述技术方案与现有技术相比具有如下优点:

在本申请实施例中,通过分析语法及逻辑层面的相似程度,可以避免被代码编译或者一些混淆加密手段影响,降低误差,解决了相关技术通过字符对比计算代码相似度误差大的技术问题,提高了重复代码的维护效率。

附图说明

此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本申请的实施例,并与说明书一起用于解释本申请的原理。

为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。

图1是根据本申请实施例的一种代码相似度的检测方法的流程图;

图2是本申请实施例扫描代码字符串的示意图;

图3是本申请实施例中ast的示意图;

图4是本申请实施例生成计数数组的两个示意图;

图5是本申请实施例两个代码块的对比示例图;

图6是本申请实施例中的对比示意图;

图7是本申请实施例三个代码块的对比示例图;

图8是根据本申请实施例的一种代码相似度的检测装置的结构框图;

图9是本申请实施例的一种电子设备的结构图。

具体实施方式

为使本申请实施例的目的、技术方案和优点更加清楚,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本申请的一部分实施例,而不是全部的实施例,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本申请保护的范围。

需要说明的是,在本文中,诸如“第一”和“第二”等之类的关系术语仅仅用来将一个实体或者操作与另一个类似的实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。

在本实施例中提供了一种代码相似度的检测方法,图1是根据本申请实施例的一种代码相似度的检测方法的流程图,如图1所示,该流程包括如下步骤:

步骤s102,解析目标代码文件的语法结构,生成所述目标代码文件的抽象语法树,其中,所述抽象语法树包括若干个节点,每个所述节点对应一个临时数组和一个计数数组;

在本实施例的抽象语法树(abstractsyntaxtree,ast)是目标代码文件中源代码的抽象语法结构的树状表现形式。

步骤s104,采用所述临时数组和所述计数数组计算所述目标代码文件中代码块的代码相似度;

本实施例通过ast对应的临时数组以及计数数组,可以计算代码在语义层面的逻辑相似度,不依赖代码的编译手段和文本本身。

通过上述步骤,解析目标代码文件的语法结构,生成所述目标代码文件的抽象语法树,所述ast的每个节点对应一个临时数组,然后采用所述ast计算所述目标代码文件的代码相似度,通过分析语法及逻辑层面的相似程度,可以避免被代码编译或者一些混淆加密手段影响,降低误差,解决了相关技术通过字符对比计算代码相似度误差大的技术问题,提高了重复代码的维护效率。

在本实施例中,解析目标代码文件的语法结构,生成所述目标代码文件的抽象语法树,包括:

s11,将所述目标代码文件中的代码字符串分割为词法单元,其中,每个词法单元对应一个代码块;

s12,基于分割后的多个词法单元生成词法单元列表;

s13,以变量定义表达式为单位将所述词法单元列表转换为ast。

在本实施例的一个实施方式中,以变量定义表达式为单位将所述词法单元列表转换为ast包括:以变量定义表达式为单位将所述词法单元列表拆分为多个临时数组,其中,每个临时数组对应一个变量定义表达式,每个变量定义表达式采用关键字符进行标识;针对所述词法单元列表的每个变量定义表达式,将对应的临时数组映射为一个子ast;将多个子ast分别确定为指定树根节点下的子节点,组合得到一个总ast。

在一个示例中,变量定义表达式的关键字符为variabledeclaration,临时数组为:variabledeclaration,variabledeclarator,identifier,literal。

在本实施例中,将所述目标代码文件中的代码字符串分割为词法单元包括:从所述目标代码文件中的代码字符串的第一个字符开始,从左向右扫描所述代码字符串,直到下一个空字符串,提取空字符串之前的连续字符串;将所述连续字符串确定为关键字符,继续从左向右扫描所述代码字符串,直到所述关键字符之后最近一个标识符,将所述关键字符到所述标识符之间的字符集确定为一个词法单元。

在扫描得到第一个词法单元之后,换行继续从左向右扫描剩下的所述代码字符串(如果还有未扫描完的代码字符串),直到扫描至所述代码字符串的最后一个字符。

可选的,标识符可以是分号或者是换行符。代码字符串的第一个字符是代码字符串从起始行(如第0行)的起始列(如第0列)开始的第一个非空字符。

在本实施例的javascript言语中,最小的逻辑执行单位是表达式(即ast节点),如vara=1,在扫描的过程中,“v”为第一个字符,“var”为关键字符,“vara=1”为一个表达式;而每个表达式都会有一个关键字符来标识这个表达式,所以可以通过识别关键字符来构建ast语法树,如字符串var在目标代码文件的代码中是一个关键字符(用于标识变量定义表达式variabledeclaration)。

图2是本申请实施例扫描代码字符串的示意图,通过逐行逐列扫描字符的方式对每一个字符都会生成一个行数x和列数y的坐标,如图2所示,从第一个字符x0y0开始扫描,为空字符则忽略,x1y0是字符v非空字符则会先记录下来,继续扫描后面的一个字符a(x2y0),直到下一个空字符(x4y0)出现为止,就可以得到从x1y0到x3y0的一个连续字符串var,而字符串var在javascript语言中是一个关键字符(变量定义表达式variabledeclaration),根据变量定义表达式在javascript中的语法逻辑就能判断出从var到最近的一个分号(x10y0)或者换行符(x11y0)(分号和换行符是javascript语言中分隔表达式的特殊字符)之间的9个字符(x1y0到x9y0)为一个表达式。

在扫描得到一个完整的表达式之后,然后拆分变量定义表达式(简称表达式),这个完整的变量定义表达式(variabledeclaration)一定可以拆分成以下组成元素(即ast中的子节点),每个组成由空字符分隔,在一个vara=0的示例中,可以按照代码位置拆分得到以下元素,进而得到对应的临时数组:

x1y0-x3y0的3个字符为var(variabledeclarator);

x5y0字符a(identifier)(此处有可能是多个连续字符,本例中只有一个字符);

x7y0固定存在运算符号=;

x9y0字符1(literal)(此处有可能是多个连续字符,本示例中只有一个字符。

另外,本示例中的literal是简单的字面量定义,此处还可以是另一个表达式,如果是表达式则作为上述中变量定义表达式variabledeclaration的子节点按照上述的拆分流程继续拆分解析)。

上述示例中的另一个表达式varb=2;和vara=1;已经由分号或换行符隔开,所以是两个独立的表达式,同属ast树根节点,以一种数组的形式临时存放各子节点,即临时数组,如下所示:

从判断出变量定义表达式variabledeclaration,再到拆分这个表达式为4个组成variabledeclaration,variabledeclarator,identifier,literal,再循环这个临时数组就可以得到这个表达式的ast树状结构。接下来只要重复上述步骤,直到扫描至所述代码字符串的最后一个字符,就可以构造出标代码文件中的代码字符串所有表达式的ast语法树,图3是本申请实施例中ast的示意图,示意了两个节点(词法单元节点1,词法单元节点2),分别对应两个表达式。下面对ast中的各个元素进行解释:

词法单元:每一个完整的子节点即为一个词法单元;

program:树根节点;

variabledeclaration:变量定义表达式;

variabledeclarator:词法单元/子节点/代码块类型(此处表示变量定义);

kind:“var”:声明变量类型;

identifier:词法单元/子节点/代码块类型(此处表示变量标识符定义);

name:“a”:声明变量名;

literal:词法单元/子节点/代码块的运算类型(此处表示字面量定义);

raw:“1”:声明变量值(字面量);

需要说明的是,上述词法单元/子节点/代码块类型,中的取值(variabledeclarator/identifier/literal)为枚举类型,其他如functiondeclaration,表示方法定义等类似。

在本实施例中,采用所述ast计算所述目标代码文件的代码相似度包括:

s21,基于所述ast中的多个临时数组对应生成多个计数数组,其中,所述计数数组包括变量定义表达式的以下信息:运算类型,变量类型,变量数量;

运算类型,变量类型,变量数量是计算重复率程度的三个维度,因为相似度只关心代码的变量与运算的定义和形式,无需关心变量名和运算符声明的位置是否一致。

可选的,基于所述ast中的多个临时数组对应生成多个计数数组包括:针对所述抽象语法树中的每个临时数组,读取所述临时数组中的第一关键字符,其中,所述第一关键字符用于表征变量定义表达式的运算类型;读取所述临时数组中的第二关键字符,并统计所述第二关键字符的变量数量,其中,所述第二关键字符用于表征当前运算类型下的变量类型,每个第二关键字符对应一个变量类型;采用所述第一关键字符、所述第二关键字符、所述变量数量生成计数数组。

在一个示例中,按照ast的树形结构从左往右依次遍历其中的任意两个代码块,或者按照策略变量ast中符合预设条件的代码块(如仅遍历运算类型为指定类型的代码块)。例如,第一代码块和第二代码块包含的表达式分别为“vara=1”和“varb=2”,临时数组,如下所示:

在第一代码块中,变量定义表达式为variabledeclaration,再拆分这个表达式为4个组成variabledeclaration,variabledeclarator,identifier,literal;在第二代码块中,变量定义表达式也为variabledeclaration,再拆分这个表达式为4个组成variabledeclaration,variabledeclarator,identifier,literal。再读取第一代码块的临时数组,则第一关键字符为“1”,运算类型为字面量定义,第二关键字符为“variabledeclarator”,该运算类型下的变量类型为变量声明,“var”的数量为1,变量数量为1。对应的,读取第二代码块的临时数组,第一关键字符为“2”,运算类型为字面量定义,第二关键字符也为“variabledeclarator”,该运算类型下的变量类型为变量声明,“var”的数量为1,变量数量也为1。

图4是本申请实施例生成计数数组的两个示意图,可以在生成临时数组的同时生成另一个计数数组(省略了运算类型),结构与临时数组类似,计数数组不需要像临时数组一样描述出完整的树状结构中的每个节点的含义(忽略不影响对比的部分,因为对比的是表达式类型而非具体的值),只记录在同一数组位置(即ast树节点位置)相同表达式的数量,以便对比统计使用。

s22,对比所述多个计数数组中的第一计数数组和第二计数数组,并将所述第一计数数组和所述第二计数数组之间的相似度确定为所述目标代码文件中第一代码块和第二代码块的相似度,其中,所述第一计数数组对应所述第一代码块,所述第二计数数组对应所述第二代码块。其中,第一代码块和第二代码块是同一个目标代码文件中任意两个待进行相似度比较的两个代码块,第一计数数组与第一代码块生成的第一临时数组对应,基于第一临时数组生成,第二计数数组与第二代码块生成的第二临时数组对应,基于第二临时数组生成。

在此以表达式为“var=1”为例进行说明,图5是本发明申请实施例两个代码块的对比示例图,虚线框为重复的部分,图5中1,2分别是一个命名为afunc的方法定义表达式的不同的实现方式,但功能是重复的。接下来通过示例说明,如何使用ast树对应的计数数组,找到重复的部分(ast中虚线部分)。

在一个示例中,对比所述多个计数数组中的第一计数数组和第二计数数组,并将所述第一计数数组和所述第二计数数组之间的相似度确定为所述目标代码文件中第一代码块和第二代码块的相似度,包括:对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;若所述第一运算类型和所述第二运算类型相同,对比所述第一计数数组的第一变量类型与所述第二计数数组的第二变量类型;若所述第一计数数组的第一变量类型与所述第二计数数组的第二变量类型相同,比较所述第一计数数组的第一变量数量与所述第二计数数组的第二变量数量;若所述第一计数数组的第一变量数量与所述第二计数数组的第二变量数量相同,确为所述目标代码文件中第一代码块和第二代码块之间的相似度为100%。

在本示例的另一方面,若所述第一运算类型和所述第二运算类型不同,直接确定所述第一代码块与所述第二代码块之间的相似度为0。

图6是本申请实施例中的对比示意图,分别用计数数组1中各层级的表达式与计数数组2中的各层级循环做对比,直到对比到第4次找到相同的type:functiondeclaration。表达式类型相同都是方法定义表达式,则继续对比该方法定义表达式的子节点nodes中的表达式type:variabledeclaration,并且两个方法定义表达式的子节点nodes中都有且只有1个type:variabledeclaration,且num为1,所以可认为上述图5中代码块1,2中的afunc方法的功能是完全一致的,相识度为100%。上述示例为相似度为100%的场景。

在一个示例中,对比所述多个计数数组中的第一计数数组和第二计数数组,并将所述第一计数数组和所述第二计数数组之间的相似度确定为所述目标代码文件中第一代码块和第二代码块的相似度,包括:对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;若所述第一运算类型和所述第二运算类型相同,计算所述第一计数数组的第一变量数量与所述第二计数数组的第二变量数量之间的第一商值,其中,所述第一商值用于表征所述第一计数数组和所述第二计数数组之间的第一相似度;将所述第一商值,确定为所述目标代码文件中第一代码块和第二代码块之间的相似度。

在一个示例中,对比所述多个计数数组中的第一计数数组和第二计数数组,并将所述第一计数数组和所述第二计数数组之间的相似度确定为所述目标代码文件中第一代码块和第二代码块的相似度,包括:对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;若所述第一运算类型和所述第二运算类型相同,计算所述第一计数数组的第一变量类型数量与所述第二计数数组的第二变量类型数量之间的第二商值所述第一变量类型数量和第二变量类型数量分别是根据所述第一运算类型和所述第二运算类型包括的变量类型种类统计得到的,其中,所述第二商值用于表征所述第一计数数组和所述第二计数数组之间的第二相似度;将所述第二商值,确定为所述目标代码文件中第一代码块和第二代码块之间的相似度。

在本示例的另一方面,若所述第一运算类型和所述第二运算类型不同,直接确定所述第一代码块与所述第二代码块之间的相似度为0。

在一个示例中,对比所述多个计数数组中的第一计数数组和第二计数数组,并将所述第一计数数组和所述第二计数数组之间的相似度确定为所述目标代码文件中第一代码块和第二代码块的相似度,包括:对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;若所述第一运算类型和所述第二运算类型相同,确定所述第一计数数组和所述第二计数数组中相同变量类型的特定变量数量,以及确定所述第一计数数组或所述第二计数数组的变量总数量,计算所述特定变量数量与所述变量总数量的第三商值,其中,所述第一计数数组和所述第二计数数组的变量总数量相同,所述第三商值用于表征所述第一计数数组和所述第二计数数组之间的第三相似度;将所述第三商值,确定为所述目标代码文件中第一代码块和第二代码块的相似度。

在本示例的另一方面,若所述第一运算类型和所述第二运算类型不同,直接确定所述第一代码块与所述第二代码块之间的相似度为0。

在此以三个代码块举例相似度低于100%的场景,代码块1包括一个表达式“vara=1”,代码块2包括两个表达式“vara=1”和“varb=1”,代码块3包括两个表达式“vara=1”和“functionb()”。不完全匹配的afunc方法定义表达式,可以通过计数数组进行对比,可以得出两个代码块的相似度,图7是本申请实施例三个代码块的对比示例图,包括1,2,3三个代码块,分别对应计数数组1,2,3,对其两两进行比较,需要说明的是,计数数组是根据临时数组生成的,那么进行两两对比时,是基于同一数组位置(即抽象语法树中树节点位置)中的运算类型、变量类型、变量数量、变量类型数量进行对比,在此进行举例说明:

计数数组1,2中的方法定义表达式type:functiondeclaration与子节点nodes的type:variabledeclaration(有且只有这一类型)类型都能匹配的上,但个数num的值不一样,即第一运算类型与第二运算类型相同,但第一变量数量与第二变量数量不同,计算第一计数数组的第一变量数量num:1与第二计数数组的第二变量数量num:2的第一商值,所以可得知1,2中的afunc方法功能有:num:1/num:2=50%,将50%作为目标代码文件中第一代码块和第二代码块之间的相似度。

计数数组1,3中,虽然type:variabledeclaration的个数num值一样,但计数数组3中多了1个子节点类型(functiondeclaration),即第一运算类型与第二运算类型相同,但第一变量类型数量与第二变量类型数量不同,计算第一计数数组的第一变量类型数量nodes个数:1与所述第二计数数组的第二变量类型数量nodes个数:2之间的第二商值,可计算出有:计数数组1nodes个数:1/计数数组3nodes个数:2=50%,将50%作为目标代码文件中第一代码块和第二代码块之间的相似度。在另一些示例中,若计数数组1中原nodes个数为3,计数数组3中原nodes个数为2,对应的,可计算出有:计数数组3nodes个数:2/计数数组1nodes个数:3=66.67%。

计数数组2,3中子节点nodes的个数都大于2(num的值等于同类型的表达式在nodes中的个数),需要先去除掉相同类型表达式,即,第一运算类型与第二运算类型相同,但第一变量类型数量与第二变量类型数量大于阈值,且存在相同变量类型,确定所述第一计数数组和所述第二计数数组中相同变量类型的特定变量数量,计数数组2、3中有1个变量类型相同type:variabledeclaration,所以计数数组2,3都需要先去掉1个type:variabledeclaration,得到相同变量类型的特定变量数量为1。这样计数数组2,3的子节点nodes中分别只剩下1个表达式类型,可以理解为,变量总数量为2,因此,可以用被去除掉的表达式数量除以原节点数量:计数数组1(计数数组3)被去除的nodes个数:1/计数数组1(计数数组3)原nodes个数:2=50%,将50%作为目标代码文件中第一代码块和第二代码块之间的相似度。

本实施例的方案并不基于字符对比,而是通过分析语法及逻辑层面的相似程度,所以不会被代码编译或者一些混淆加密手段影响。(代码编译或混淆加密是指通过技术手段,打乱代码顺序,改变变量名,加密变量值等,而不会改变代码的语义逻辑结构)由于重复代码的维护需要非常高的人力成本(一个地方的修改无法同步到所有),所以公共代码的提取和抽象化是开发中的重中之重,本方案则是为抽取和抽象化提供了条件,帮开发者找出哪些代码是值得被公共化的,极大减少了代码的维护成本。

通过以上的实施方式的描述,本领域的技术人员可以清楚地了解到根据上述实施例的方法可借助软件加必需的通用硬件平台的方式来实现,当然也可以通过硬件,但很多情况下前者是更佳的实施方式。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质(如rom/ram、磁碟、光盘)中,包括若干指令用以使得一台终端设备(可以是手机,计算机,服务器,或者网络设备等)执行本申请各个实施例所述的方法。

在本实施例中还提供了一种代码相似度的检测装置,用于实现上述实施例及优选实施方式,已经进行过说明的不再赘述。如以下所使用的,术语“模块”可以实现预定功能的软件和/或硬件的组合。尽管以下实施例所描述的装置较佳地以软件来实现,但是硬件,或者软件和硬件的组合的实现也是可能并被构想的。

图8是根据本申请实施例的一种代码相似度的检测装置的结构框图,如图8所示,该装置包括:生成模块80,计算模块82,其中,

生成模块80,用于解析目标代码文件的语法结构,生成所述目标代码文件的抽象语法树,其中,所述抽象语法树包括若干个节点,每个所述节点对应一个临时数组和一个计数数组;

计算模块82,用于采用所述临时数组和所述计数数组计算所述目标代码文件中代码块的代码相似度。

可选的,所述计算模块包括:生成单元,用于基于所述ast中的多个临时数组对应生成多个计数数组,其中,所述计数数组包括变量定义表达式的以下信息:运算类型,变量类型,变量数量;对比单元,用于对比所述多个计数数组中的第一计数数组和第二计数数组,并将所述第一计数数组和所述第二计数数组之间的相似度确定为所述目标代码文件中第一代码块和第二代码块的相似度,其中,所述第一计数数组对应所述第一代码块,所述第二计数数组对应所述第二代码块。

可选的,所述生成单元包括:第一读取子单元,用于针对所述ast中的每个临时数组,读取所述临时数组中的第一关键字符,其中,所述第一关键字符用于表征变量定义表达式的运算类型;第二读取子单元,用于读取所述临时数组中的第二关键字符,并统计所述第二关键字符的变量数量,其中,所述第二关键字符用于表征当前运算类型下的变量类型,每个第二关键字符对应一个变量类型;生成子单元,用于采用所述第一关键字符、所述第二关键字符、所述变量数量生成计数数组。

可选的,所述对比单元包括:对比子单元,用于对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;第一计算子单元,用于若所述第一运算类型和所述第二运算类型相同,计算所述第一计数数组的第一变量数量与所述第二计数数组的第二变量数量之间的第一商值,其中,所述第一商值用于表征所述第一计数数组和所述第二计数数组之间的第一相似度;第一确定子单元,用于将所述第一商值,确定为所述目标代码文件中第一代码块和第二代码块之间的相似度。

可选的,所述对比单元包括:对比子单元,用于对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;第二计算子单元,用于若所述第一运算类型和所述第二运算类型相同,计算所述第一计数数组的第一变量类型数量与所述第二计数数组的第二变量类型数量之间的第二商值,所述第一变量类型数量和第二变量类型数量分别是根据所述第一运算类型和所述第二运算类型包括的变量类型种类统计得到的,其中,所述第二商值用于表征所述第一计数数组和所述第二计数数组之间的第二相似度;第二确定子单元,用于将所述第二商值,确定为所述目标代码文件中第一代码块和第二代码块之间的相似度。

可选的,所述对比单元包括:对比子单元,用于对比所述第一计数数组的第一运算类型与所述第二计数数组的第二运算类型;第三计算子单元,用于若所述第一运算类型和所述第二运算类型相同,确定所述第一计数数组和所述第二计数数组中相同变量类型的特定变量数量,以及确定所述第一计数数组或所述第二计数数组的变量总数量,计算所述特定变量数量与所述变量总数量的第三商值,其中,所述第一计数数组和所述第二计数数组的变量总数量相同,所述第三商值用于表征所述第一计数数组和所述第二计数数组之间的第三相似度;第三确定子单元,用于将所述第三商值,确定为所述目标代码文件中第一代码块和第二代码块的相似度。

可选的,所述生成模块包括:分割单元,用于将所述目标代码文件中的代码字符串分割为词法单元,其中,每个词法单元对应一个代码块;生成单元,用于基于分割后的多个词法单元生成词法单元列表;转换单元,用于以变量定义表达式为单位将所述词法单元列表转换为ast。

可选的,所述转换单元包括:拆分子单元,用于以变量定义表达式为单位将所述词法单元列表拆分为多个临时数组,其中,每个临时数组对应一个变量定义表达式,每个变量定义表达式采用关键字符进行标识;映射子单元,用于针对所述词法单元列表的每个变量定义表达式,将对应的临时数组映射为一个子ast;组合子单元,用于将多个子ast分别确定为指定树根节点下的子节点,组合得到一个总ast。

可选的,所述分割单元包括:扫描子单元,用于从所述目标代码文件中的代码字符串的第一个字符开始,从左向右扫描所述代码字符串,直到下一个空字符串,提取空字符串之前的连续字符串;确定子单元,用于将所述连续字符串确定为关键字符,继续从左向右扫描所述代码字符串,直到所述关键字符之后最近一个标识符,将所述关键字符到所述标识符之间的字符集确定为一个词法单元;处理子单元,用于换行继续从左向右扫描剩下的所述代码字符串,直到扫描至所述代码字符串的最后一个字符。

需要说明的是,上述各个模块是可以通过软件或硬件来实现的,对于后者,可以通过以下方式实现,但不限于此:上述模块均位于同一处理器中;或者,上述各个模块以任意组合的形式分别位于不同的处理器中。

本申请实施例还提供了一种电子设备,图9是本申请实施例的一种电子设备的结构图,如图9所示,包括处理器91、通信接口92、存储器93和通信总线94,其中,处理器91,通信接口92,存储器93通过通信总线94完成相互间的通信,存储器93,用于存放计算机程序;处理器91,用于执行存储器43上所存放的程序时,实现实施例中任一所述的代码相似度的检测方法。

上述终端提到的通信总线可以是外设部件互连标准(peripheralcomponentinterconnect,简称pci)总线或扩展工业标准结构(extendedindustrystandardarchitecture,简称eisa)总线等。该通信总线可以分为地址总线、数据总线、控制总线等。为便于表示,图中仅用一条粗线表示,但并不表示仅有一根总线或一种类型的总线。

通信接口用于上述终端与其他设备之间的通信。

存储器可以包括随机存取存储器(randomaccessmemory,简称ram),也可以包括非易失性存储器(non-volatilememory),例如至少一个磁盘存储器。可选的,存储器还可以是至少一个位于远离前述处理器的存储装置。

上述的处理器可以是通用处理器,包括中央处理器(centralprocessingunit,简称cpu)、网络处理器(networkprocessor,简称np)等;还可以是数字信号处理器(digitalsignalprocessing,简称dsp)、专用集成电路(applicationspecificintegratedcircuit,简称asic)、现场可编程门阵列(field-programmablegatearray,简称fpga)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。

在本申请提供的又一实施例中,还提供了一种计算机可读存储介质,该计算机可读存储介质中存储有指令,当其在计算机上运行时,使得计算机执行上述实施例中任一所述的代码相似度的检测方法。

根据本申请的一个方面,提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备执行上述代码相似度的检测方法中任一实施例的步骤。

在上述实施例中,可以全部或部分地通过软件、硬件、固件或者其任意组合来实现。当使用软件实现时,可以全部或部分地以计算机程序产品的形式实现。所述计算机程序产品包括一个或多个计算机指令。在计算机上加载和执行所述计算机程序指令时,全部或部分地产生按照本申请实施例所述的流程或功能。所述计算机可以是通用计算机、专用计算机、计算机网络、或者其他可编程装置。所述计算机指令可以存储在计算机可读存储介质中,或者从一个计算机可读存储介质向另一个计算机可读存储介质传输,例如,所述计算机指令可以从一个网站站点、计算机、服务器或数据中心通过有线(例如同轴电缆、光纤、数字用户线(dsl))或无线(例如红外、无线、微波等)方式向另一个网站站点、计算机、服务器或数据中心进行传输。所述计算机可读存储介质可以是计算机能够存取的任何可用介质或者是包含一个或多个可用介质集成的服务器、数据中心等数据存储设备。所述可用介质可以是磁性介质,(例如,软盘、硬盘、磁带)、光介质(例如,dvd)、或者半导体介质(例如固态硬盘solidstatedisk(ssd))等。

以上所述仅为本申请的较佳实施例而已,并非用于限定本申请的保护范围。凡在本申请的精神和原则之内所作的任何修改、等同替换、改进等,均包含在本申请的保护范围内。

以上所述仅是本申请的具体实施方式,使本领域技术人员能够理解或实现本申请。对这些实施例的多种修改对本领域的技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本申请的精神或范围的情况下,在其它实施例中实现。因此,本申请将不会被限制于本文所示的这些实施例,而是要符合与本文所申请的原理和新颖特点相一致的最宽的范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1