提出了改进的AC-BM算法,将待匹配的字符串集合转换为一个类似于Aho-Corasick算法的树状有限状态自动机。匹配时,采取自后向前的方法,并借用BM算法的坏字符跳转和好前缀跳转技术。改进的AC-BM算法借助BMH算法思想,取消了原AC-BM算法的好前缀跳转,并对坏字符跳转部分的计算进行优化。新算法修改了skip的计算方法,不再保留每个节点的好前缀跳转参数及坏字符跳转参数,因此匹配只与当前匹配字符有关,而与当前节点无关,可以实现大小写正文的识别。关 键 词 算法; 字符串匹配; 内容分析; 入侵检测Abstract ACBM is a Boyer-Moore like algorithm applied to a set of keywords held in an Aho-Corassick like keyword tree that overlays common prefixes of the keywords. The algorithm takes the best characteristics of both the Boyer-Moore and Aho-Corasick. Based on the idea of Boyer-Moore-Horspool, we make an improvement to AC-BM algorithm. In the improved version, the Good Prefix Shift is not performed, the Bad Character Shift function is improved, the Goto procedure is also modified which do not keep the parameters of Good Prefix Shift and Bad Character Shift.Key words algorithm; string matching; content analysis; intrusion detection字符串匹配是指在文本Textt=t1t2…tn中检索子串Patp=p1p2…pm的所有出现。字符串匹配可分为单字符串匹配和字符串集合匹配两种。单字符串匹配算法最著名的是KMP(Knuth-Morris-Pratt)算法和BM(Boyer-Moore)算法。KMP算法实现了无回溯匹配,字符串中的每个字符只匹配一次,时间复杂度为O(n+m)[1];BM算法采用跳跃方式,匹配时跳过不需匹配的字符,最优情况下的时间复杂度为O(n/m),平均情况下也大大优于KMP算法[2];文献[3]取掉BM算法的好后缀试探(Good Suffix Heuristic),形成BMH(Boyer-Moore-Horspool)算法,实验证明BMH算法性能在自然语言环境下比原始BM算法还要好。字符串集合匹配是从文本Text中一次查找多个字符串P1,P2,…,Pm的所有出现,最经典的是AC(Aho and Corasick)算法。该算法将待匹配的多个字符串转换为树状有限状态自动机,然后进行扫描匹配,最优情况和平均情况的时间复杂度都为O(n)[4];文献[5]提出了一种类似于AC和BM的算法,即Aho-Corasick_Boyer-Moore(AC_BM)混合算法。该算法根据包过滤的规则前缀共同信息较多的特点,采取自后向前的搜索方法,因此在速度方面具有较高的优越性[6]。本文对AC-BM算法提出改进,并根据BMH算法的思想,取消好前缀跳转(Good Prefix Shift),测试结果表明,该算法在数据包过滤、内容分析与审计等应用中,优于AC-BM算法。1 AC-BM算法描述AC-BM算法将待匹配的字符串集合转换为一个类似于Aho-Corasick算法的树状有限状态自动机,但构建时不是基于字符串的后缀而是前缀。匹配时,采取自后向前的方法,并借用BM算法的坏字符跳转(BadCharacter Shift)和好前缀跳转(Good Prefix Shift)技术。坏字符跳转即当字符串树中的字符与被匹配内容x失配时,将字符串树跳转到下一个x的出现位置,如果x的字符串树不存在,则将字符串树向左移动字符串树的最小字符串长度。好前缀跳转即当字符串树中的字符与被匹配内容x失配时,将字符串树跳转到字符串树中一个与被测正文部分等同的位置。这个等同部分可以是字符串树中某字符串的子串(子串跳转),也可以是一个字符串的后缀(后缀跳转)。例如,设有规则ethernetmovesme,ethernetisking,ethernetisdead和ethernetforever,要检查的数据包内容为nothingtoworryaboutinthis。首先,构造字符串有限状态自动机,如图1a。匹配从字符r开始,显然r与e不匹配,由于字符串树中下一个r出现在深度5的位置,字符串树的最小字符串长度为14,根据坏字符跳转,字符串树可以安全向左移动5个字符,如图1b。