【讨论】关于内存查找的最快算法
自己写了个程序仿照 OD 的内存数据查找功能,比如在内存中查找 ff 25 ?? ?? ?? ?? c3。
然后做了个测试:
被查找文件大小:1M
特征字符串长度:6字节 (改特征字符串不存在)
循环:10000次
CPU:P4 3.0G
结果:用了约12s
我觉得自己的算法不好,竟然用了这么多时间。
希望大家可以指点下。
附程序:
// BinFind.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
LPBYTE FindBin(LPBYTE lpBuf, size_t iBufBytes, LPBYTE lpMarkBuf, LPBYTE lpMarkFormat, size_t iMarkBufBytes);
int _tmain(int argc, _TCHAR* argv[])
{
//BYTE data[] = {0x80, 0x39, 0x00, 0x75, '?', '?', 0xff};
//BYTE format[] = {'-', '-', '-', '-', '?', '?', '-'};
BYTE data[] = {0x80, 0x39, 0x00, 0x75, 0x03, 0x0};
BYTE format[] = {'-', '-', '-', '-', '-', '-',};
TCHAR *lpszFileName = _T("abc.exe");
HANDLE hFile = CreateFile( lpszFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
DWORD dwFileSize = GetFileSize(hFile, NULL);
HANDLE hMapFile = CreateFileMapping( hFile,
NULL,
PAGE_READONLY,
0,
0,
NULL );
LPBYTE lpFile = (LPBYTE)MapViewOfFile( hMapFile,
FILE_MAP_READ,
0,
0,
0 );
DWORD i=10000;
LPBYTE lpAddr;
DWORD dw1 = GetTickCount();
while (--i)
lpAddr = FindBin(lpFile, dwFileSize, data, format, sizeof(data));
DWORD dw2 = GetTickCount();
printf("%x \n", lpAddr);
printf("%d \n", dw2-dw1);
return 0;
}
LPBYTE FindBin(LPBYTE lpBuf, size_t iBufBytes,
LPBYTE lpMarkBuf, LPBYTE lpMarkFormat, size_t iMarkBufBytes)
{
LPBYTE lpdata = lpBuf;
size_t size = iBufBytes;
BYTE CmpData = *lpMarkBuf;
BOOL result = FALSE;
while (size > 0)
{
// 查找第1个字符
while ((--size) && (*lpdata != CmpData))
lpdata++;
if (*lpdata != CmpData)
break; // 没有找到
if (size < iMarkBufBytes)
break; // 剩余比较的字节不够
// 比较特征字符
LPBYTE lp1 = lpdata + 1;
LPBYTE lp2 = lpMarkBuf + 1;
LPBYTE lp3 = lpMarkFormat + 1;
size_t j = iMarkBufBytes - 1;
while (--j)
{
if ((*lp3 != '?') && (*lp1 != *lp2))
break;
lp1++, lp2++, lp3++;
}
if (*lp1 == *lp2)
{ // 找到了
result = TRUE;
break;
}
lpdata++;
}
if (result)
return lpdata;
else
return NULL;
}