飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 11614|回复: 16

一个基于KMP优化算法的数据块匹配算法类

  [复制链接]
  • TA的每日心情
    开心
    2018-9-27 19:17
  • 签到天数: 31 天

    [LV.5]常住居民I

    发表于 2014-9-28 21:52:08 | 显示全部楼层 |阅读模式
    本帖最后由 lucky_789 于 2015-6-2 23:13 编辑

    KMP算法大家都知道是一种改进的字符串匹配算法,我这里将其略作修改,使其能作数据块匹配,即不限于字符串匹配,并封装成类。
    本算法类主要参考并基于July的博文《从头到尾彻底理解KMP》(http://blog.csdn.net/v_july_v/article/details/7041827)
    1. // KmpDataSearch.h: Search data block from another and return the FIRST matched location.
    2. //
    3. //////////////////////////////////////////////////////////////////////
    4. /********************************************************************/
    5. /* 单元名称: KmpSearchData类                                        */
    6. /* 单元作者: lucky_789[PYG]                                         */
    7. /* 说    明: 修改自July的KMP优化算法                                */
    8. /********************************************************************/

    9. #if !defined(AFX_KmpSearchData_H__INCLUDED_)
    10. #define AFX_KmpSearchData_H__INCLUDED_

    11. #if _MSC_VER > 1000
    12. #pragma once
    13. #endif

    14. #include <windows.h>


    15. class KmpSearchData  
    16. {
    17. public:
    18.         int WINAPI KmpSearch(char* s, int sSize, char* p, int pSize);
    19.         void GetNext(char* p, int sSize, int next[]) ;
    20.         KmpSearchData();
    21.         virtual ~KmpSearchData();
    22. };

    23. #endif // !defined(AFX_KmpSearchData_H__INCLUDED_)
    复制代码
    1. // KmpDataSearch.cpp: Search data block from another and return the FIRST matched location.
    2. //
    3. //////////////////////////////////////////////////////////////////////
    4. /********************************************************************/
    5. /* 单元名称: KmpSearchData类                                        */
    6. /* 单元作者: lucky_789[PYG]                                         */
    7. /* 说    明: 修改自July的KMP优化算法                                */
    8. /********************************************************************/

    9. #include "KmpSearchData.h"

    10. //////////////////////////////////////////////////////////////////////
    11. // Construction/Destruction
    12. //////////////////////////////////////////////////////////////////////

    13. KmpSearchData::KmpSearchData()
    14. {
    15. }

    16. KmpSearchData::~KmpSearchData()
    17. {
    18. }

    19. /**************************************************************************/
    20. /* 函数名称: KmpSearch                                                    */
    21. /* 函数作者: lucky_789[PYG]                                               */
    22. /* 函数参数: s:    要在其中查找目标数据的源数据块                         */
    23. /*           sSize:源数据块的字节数。中间可能存在'\0',故不能用strlen(s)   */
    24. /*           p:    查找的模式数据块(在s中查找p的位置)                     */
    25. /*           pSize:查找的模式数据块大小(字节数)                           */
    26. /**************************************************************************/
    27. int WINAPI KmpSearchData::KmpSearch(char *s, int sSize, char *p, int pSize)  
    28. {  
    29.     int i = 0;  
    30.     int j = 0;  
    31.     int sLen = sSize;  
    32.     int pLen = pSize;
    33.     int *next = new int[pSize];

    34.     memset(next, 0, pSize * sizeof(int));
    35.     GetNext(p, pSize, next);

    36.     while (i < sLen && j < pLen)  
    37.     {  
    38.         //①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++      
    39.         if (j == -1 || s[i] == p[j])  
    40.         {  
    41.             i++;  
    42.             j++;  
    43.         }  
    44.         else  
    45.         {  
    46.             //②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]      
    47.             //next[j]即为j所对应的next值        
    48.             j = next[j];  
    49.         }  
    50.     }

    51.     delete next;  
    52.     if (j == pLen)  
    53.         return i - j;  
    54.     else  
    55.         return -1;  
    56. }  


    57. /**************************************************************************/
    58. /* 函数名称: GetNext                                                      */
    59. /* 函数作者: lucky_789[PYG]                                               */
    60. /* 函数参数: p:    查找的模式数据块(在s中查找p的位置)                     */
    61. /*           pSize:查找的模式数据块大小(字节数)                           */
    62. /*           next: 优化过后的next数组                                     */
    63. /**************************************************************************/  
    64. void KmpSearchData::GetNext(char *p, int pSize, int next[])  
    65. {  
    66.     int pLen = pSize;  
    67.     next[0] = -1;  
    68.     int k = -1;  
    69.     int j = 0;  
    70.     while (j < pLen - 1)  
    71.     {  
    72.         //p[k]表示前缀,p[j]表示后缀   
    73.         if (k == -1 || p[j] == p[k])  
    74.         {  
    75.             ++j;  
    76.             ++k;  
    77.             //较之前next数组求法,改动在下面4行  
    78.             if (p[j] != p[k])  
    79.                 next[j] = k;   //之前只有这一行  
    80.             else  
    81.                 //因为不能出现p[j] = p[ next[j ]],所以当出现时需要继续递归,k = next[k] = next[next[k]]  
    82.                 next[j] = next[k];  
    83.         }  
    84.         else  
    85.         {  
    86.             k = next[k];  
    87.         }  
    88.     }  
    89. }

    复制代码
    1. #include <iOStream>
    2. #include "KmpSearchData.h"

    3. using namespace std;

    4. KmpSearchData KmpSearch;


    5. int main()
    6. {
    7.             char szbuf[MAX_PATH] = {0};
    8.             char s[0x200] =
    9.                 {
    10.                     0x00, 0x00, 0xbd, 0x10, 0x00, 0x00, 0x00, 0xc7, 0x44, 0x24, 0x44, 0x08, 0x00, 0x00, 0x00, 0x8b,\
    11.                         0x54, 0x24, 0x44, 0x89, 0x54, 0x24, 0x30, 0xbb, 0x01, 0x00, 0x00, 0x00, 0x90, 0x3d, 0x00, 0x00,\
    12.                         0x00, 0x01, 0x73, 0x14, 0x8b, 0x54, 0x24, 0x48, 0x0f, 0xb6, 0x3a, 0xc1, 0xe6, 0x08, 0xc1, 0xe0,\
    13.                         0x08, 0x0b, 0xf7, 0x42, 0x89, 0x54, 0x24, 0x48, 0x8b, 0x14, 0x99, 0x8b, 0xf8, 0xc1, 0xef, 0x0b,\
    14.                         0x0f, 0xaf, 0xfa, 0x3b, 0xf7, 0x73, 0x15, 0x8b, 0xc7, 0xbf, 0x00, 0x08, 0x00, 0x00, 0x2b, 0xfa,\
    15.                         0xc1, 0xef, 0x05, 0x03, 0xfa, 0x89, 0x3c, 0x99, 0x03, 0xdb, 0xeb, 0x12, 0x2b, 0xc7, 0x2b, 0xf7,\
    16.                         0x8b, 0xfa, 0xc1, 0xef, 0x05, 0x2b, 0xd7, 0x89, 0x14, 0x99, 0x8d, 0x5c, 0x1b, 0x01, 0xba, 0x01,\
    17.                         0x00, 0x00, 0x00, 0x29, 0x54, 0x24, 0x30, 0x75, 0xa4, 0x8b, 0x4c, 0x24, 0x44, 0x8b, 0xfa, 0xd3,\
    18.                         0xe7, 0x2b, 0xef, 0x03, 0xdd, 0x83, 0x7c, 0x24, 0x10, 0x04, 0x89, 0x5c, 0x24, 0x18, 0x0f, 0x8d,\
    19.                         0xbb, 0x01, 0x00, 0x00, 0x83, 0x44, 0x24, 0x10, 0x07, 0x83, 0xfb, 0x04, 0x7c, 0x05, 0xbb, 0x03,\
    20.                         0x00, 0x00, 0x00, 0x8b, 0x4c, 0x24, 0x20, 0xc1, 0xe3, 0x08, 0x8d, 0x9c, 0x0b, 0xc0, 0x06, 0x00,\
    21.                         0x00, 0xbd, 0x06, 0x00, 0x00, 0x00, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00,\
    22.                         0x00, 0x01, 0x73, 0x14, 0x8b, 0x4c, 0x24, 0x48, 0x0f, 0xb6, 0x39, 0xc1, 0xe6, 0x08, 0xc1, 0xe0,\
    23.                         0x08, 0x0b, 0xf7, 0x41, 0x89, 0x4c, 0x24, 0x48, 0x8b, 0x0c, 0x93, 0x8b, 0xf8, 0xc1, 0xef, 0x0b,\
    24.                         0x0f, 0xaf, 0xf9, 0x3b, 0xf7, 0x73, 0x15, 0x8b, 0xc7, 0xbf, 0x00, 0x08, 0x00, 0x00, 0x2b, 0xf9,\
    25.                         0xc1, 0xef, 0x05, 0x03, 0xf9, 0x89, 0x3c, 0x93, 0x03, 0xd2, 0xeb, 0x12, 0x2b, 0xc7, 0x2b, 0xf7,\
    26.                         0x8b, 0xf9, 0xc1, 0xef, 0x05, 0x2b, 0xcf, 0x89, 0x0c, 0x93, 0x8d, 0x54, 0x12, 0x01, 0x83, 0xed,\
    27.                         0x01, 0x75, 0xaa, 0x83, 0xea, 0x40, 0x83, 0xfa, 0x04, 0x8b, 0xea, 0x0f, 0x8c, 0xdc, 0x00, 0x00,\
    28.                         0x00, 0x8b, 0xca, 0xd1, 0xf9, 0x83, 0xe5, 0x01, 0x49, 0x83, 0xcd, 0x02, 0x83, 0xfa, 0x0e, 0x89,\
    29.                         0x4c, 0x24, 0x30, 0x7d, 0x13, 0xd3, 0xe5, 0x8b, 0xcd, 0x2b, 0xca, 0x8b, 0x54, 0x24, 0x20, 0x8d,\
    30.                         0x8c, 0x8a, 0xbc, 0x0a, 0x00, 0x00, 0xeb, 0x45, 0x8b, 0x54, 0x24, 0x48, 0x83, 0xe9, 0x04, 0x3d,\
    31.                         0x00, 0x00, 0x00, 0x01, 0x73, 0x0c, 0x0f, 0xb6, 0x3a, 0xc1, 0xe6, 0x08, 0xc1, 0xe0, 0x08, 0x0b,\
    32.                         0xf7, 0x42, 0xd1, 0xe8, 0x03, 0xed, 0x3b, 0xf0, 0x72, 0x05, 0x2b, 0xf0, 0x83, 0xcd, 0x01, 0x83,\
    33.                         0xe9, 0x01, 0x75, 0xdb, 0x8b, 0x4c, 0x24, 0x20, 0x81, 0xc1, 0x88, 0x0c, 0x00, 0x00, 0x89, 0x54,\
    34.                         0x24, 0x48, 0xc1, 0xe5, 0x04, 0xc7, 0x44, 0x24, 0x30, 0x04, 0x00, 0x00, 0x00, 0xbb, 0x01, 0x00,\
    35.                         0x00, 0x00, 0x89, 0x5c, 0x24, 0x44, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00,\
    36.                         0x00, 0x01, 0x73, 0x14, 0x8b, 0x54, 0x24, 0x48, 0x0f, 0xb6, 0x3a, 0xc1, 0xe6, 0x08, 0xc1, 0xe0,\
    37.                         0x08, 0x0b, 0xf7, 0x42, 0x89, 0x54, 0x24, 0x48, 0x8b, 0x14, 0x99, 0x8b, 0xf8, 0xc1, 0xef, 0x0b,\
    38.                         0x0f, 0xaf, 0xfa, 0x3b, 0xf7, 0x73, 0x15, 0x8b, 0xc7, 0xbf, 0x00, 0x08, 0x00, 0x00, 0x2b, 0xfa,\
    39.                         0xc1, 0xef, 0x05, 0x03, 0xfa, 0x89, 0x3c, 0x99, 0x03, 0xdb, 0xeb, 0x16, 0x2b, 0xc7, 0x2b, 0xf7,\
    40.                         0x8b, 0xfa, 0xc1, 0xef, 0x05, 0x2b, 0xd7, 0x0b, 0x6c, 0x24, 0x44, 0x89, 0x14, 0x99, 0x8d, 0x5c,\
    41.                         0x1b, 0x01, 0xd1, 0x64, 0x24, 0x44, 0x83, 0x6c, 0x24, 0x30, 0x01, 0x75, 0xa0, 0x83, 0xc5, 0x01
    42.                 };
    43.             char p[0x40] =
    44.                 {
    45.                     0xf7, 0x42, 0xd1, 0xe8, 0x03, 0xed, 0x3b, 0xf0, 0x72, 0x05, 0x2b, 0xf0, 0x83, 0xcd, 0x01, 0x83,\
    46.                         0xe9, 0x01, 0x75, 0xdb, 0x8b, 0x4c, 0x24, 0x20, 0x81, 0xc1, 0x88, 0x0c, 0x00, 0x00, 0x89, 0x54,\
    47.                         0x24, 0x48, 0xc1, 0xe5, 0x04, 0xc7, 0x44, 0x24, 0x30, 0x04, 0x00, 0x00, 0x00, 0xbb, 0x01, 0x00,\
    48.                         0x00, 0x00, 0x89, 0x5c, 0x24, 0x44, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00
    49.                 };

    50.         int Position = KmpSearch.KmpSearch(s, 0x200, p, 0x40);
    51.                 if (Position == -1)
    52.                         cout<<"Data block not found! "<<endl;
    53.                 else
    54.                 {
    55.                         sprintf(szbuf, "Data block found! Position = %08X", Position);
    56.                     cout<<szbuf<<endl;
    57.                 }

    58.                 system("pause");
    59.                 return 0;
    60. }
    复制代码



    评分

    参与人数 1威望 +4 飘云币 +4 收起 理由
    expasy + 4 + 4 赞一个!

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-2-26 11:14
  • 签到天数: 459 天

    [LV.9]以坛为家II

    发表于 2014-9-28 22:12:42 | 显示全部楼层
    沙发没了
    收藏学习
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2025-1-4 10:11
  • 签到天数: 490 天

    [LV.9]以坛为家II

    发表于 2014-9-28 22:17:27 | 显示全部楼层
    我只膜拜……以后收藏。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2024-12-11 12:41
  • 签到天数: 161 天

    [LV.7]常住居民III

    发表于 2014-9-28 22:31:54 | 显示全部楼层
    看不懂,只有观望+膜拜!
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    3 天前
  • 签到天数: 1693 天

    [LV.Master]伴坛终老

    发表于 2014-9-29 08:11:04 | 显示全部楼层
    看不懂,也要支持一下啦,国庆快乐
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2016-1-13 12:25
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-9-29 08:18:32 | 显示全部楼层
    不错哦,下载测试,希望楼主搞起X64 KMP,发X64版去

    点评

    X64还是有点怵。先研究研究你的签名档  详情 回复 发表于 2014-9-29 12:36
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2015-8-23 23:49
  • 签到天数: 27 天

    [LV.4]偶尔看看III

    发表于 2014-9-29 08:55:22 | 显示全部楼层
    好强悍的789!

    点评

    在别人的基础上略作修改而已,没什么贡献,还是不能实现像dup那样的搜索特征码功能,主要是想引出N姐姐的“一个搜索算法”  详情 回复 发表于 2014-9-29 12:43
    PYG19周年生日快乐!
  • TA的每日心情
    无聊
    2024-1-15 22:57
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-9-29 11:11:43 | 显示全部楼层
    这年头,搜索不用个kmp都不好意思跟人打招呼
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-9-27 19:17
  • 签到天数: 31 天

    [LV.5]常住居民I

     楼主| 发表于 2014-9-29 12:36:15 | 显示全部楼层
    small-q 发表于 2014-9-29 08:18
    不错哦,下载测试,希望楼主搞起X64 KMP,发X64版去

    X64还是有点怵。先研究研究你的签名档
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表