打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
project:useful_code_slice:boyer_moore_algorithm [Xie Yubo‘s Wiki]

Boyer Moore 算法

说明

代码所演示的算法就是参考文献1中的“Quick Search”算法,它实际是由BM算法改进而来,只使用了“坏字符启发”策略,其它时候按“Strict Forward”算法处理,实际运算的速度相当快。

这里对上述算法进行了一个很小的改动,加入了对中英文混合,也即单字节词与双字节词混合的支持。在使用原算法找出疑似匹配串后,再确定一下是否是一个词(可以是单字节词,也可以是双字节词)的起点,如果不是,则跳过匹配串,从下一个词开始重新匹配。

源代码是由纯汇编写的,如下:

;改进型的bm匹配算法 支持中英文混合(即单字节与双字节词混合;用nasm编译;函数原型;extern "C" bool sfstrstr(unsigned int td[256], const char* str1, const char* str2, char case_table[256]);;其中:;   td内的所有元素需在最初被初始化为0;   casetable是一个大小写转换用的转换表,加快大小写转换的速度,需用如下的方法生成;   for(int i = 0; i < 256; ++i) ;      casetable[i] = tolower(i);;;如果匹配成功返回true(1), 否则返回false(0);;xieyubo@gmail.com;;Last Modified: 2005.10.15 [BITS 32][global sfstrstr] countstrlen:    xor eax, eax        _countstrlen_loop:    cmp [esi + eax], byte 0    je _countstrlen_exit    inc eax    jmp _countstrlen_loop     _countstrlen_exit:    ret lower:    mov al, [esp + 4]    and eax, 0xff    add eax, [ebp + 20]    mov al, [eax]    mov [esp + 4], al    ret getnumcnword:    xor eax, eax    xor ebx, ebx     _getnumcnword_loop:    cmp ebx, [ebp - 8]    je _getnumcnword_exit    mov edx, [ebp + 12]    add edx, ebx    test [edx], byte 0x80    jz _getnumcnword_loop_goto    inc eax        _getnumcnword_loop_goto:    inc ebx    jmp _getnumcnword_loop     _getnumcnword_exit:    ret inittd:    mov esi, [ebp + 16]    mov edi, [ebp + 8]    xor ecx, ecx          _inittd_loop:    mov eax, [ebp - 12]    cmp ecx, eax    jnl _inittd_exit    mov edx, eax    sub edx, ecx    push dword [esi + ecx]    call lower    pop eax    and eax, 0xff    mov [edi + eax * 4], edx        inc ecx    jmp _inittd_loop        _inittd_exit:    ret resettd:    mov esi, [ebp + 16]    mov edi, [ebp + 8]    xor ecx, ecx          _resettd_loop:    cmp ecx, [ebp - 12]    jnl _resettd_exit    push dword [esi + ecx]    call lower    pop eax    and eax, 0xff    mov [edi + eax * 4], dword 0        inc ecx    jmp _resettd_loop        _resettd_exit:    ret        sfstrstr:    push ebp    mov ebp, esp    sub esp, 20    push esi    push edi        ;;strlen(str1)    mov esi, [ebp + 12]    call countstrlen    mov [ebp - 16], eax        ;;strlen(str2)    mov esi, [ebp + 16]    call countstrlen    mov [ebp - 12], eax        call inittd        mov esi, [ebp + 16]    mov edi, [ebp + 12]    mov [ebp - 4], dword 0    mov [ebp - 8], dword 0        _sfstrstr_loop2:    xor ecx, ecx    mov eax, [ebp - 8]    add eax, [ebp - 12]    cmp eax, [ebp - 16]    jg  _sfstrstr_loop2_exit        _sfstrstr_loop3:    cmp ecx, [ebp - 12]    jnl _sfstrstr_loop3_exit    mov eax, [ebp - 8]    add eax, ecx    push dword [edi + eax]    call lower    pop ebx    push dword [esi + ecx]    call lower    pop edx    cmp bl, dl    jne _sfstrstr_loop3_exit    inc ecx    jmp _sfstrstr_loop3        _sfstrstr_loop3_exit:    cmp ecx, [ebp - 12]    jne _sfstrstr_goto1    call getnumcnword    test eax, 0x00000001    jz _sfstrstr_goto3    mov eax, [ebp - 12]    inc eax    add [ebp - 8], eax    jmp _sfstrstr_loop2     _sfstrstr_goto3:    mov [ebp - 4], dword 1    jmp _sfstrstr_loop2_exit     _sfstrstr_goto1:    mov eax, [ebp - 8]    add eax, [ebp - 12]    push dword [edi + eax]    call lower    pop eax    and eax, 0xff    shl eax, 2    add eax, [ebp + 8]    mov eax, [eax]    cmp eax, 0    je _sfstrstr_goto2    add [ebp - 8], eax    jmp _sfstrstr_loop2     _sfstrstr_goto2:    mov eax, [ebp - 12]    inc eax    add [ebp - 8], eax    jmp _sfstrstr_loop2     _sfstrstr_loop2_exit:    call resettd    mov eax, [ebp - 4]        return:    pop edi    pop esi    mov esp, ebp    pop ebp    ret

参考文献

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
BASM for beginners, lesson 5
i++循环与i--循环的执行效率 - 程序设计 - CUDev
逆向工程
IDA简易教程
软件脱壳、破重启验证、追码、制作内存注册机
一个简单的C++程序反汇编解析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服