Sunday比KMP更适合内存特征码搜索,因其在无规律二进制模式下跳得准、写得快、出错少;KMP的next数组在无重复特征码中几乎全0而退化为暴力匹配,Sunday则每次失配至少跳过1字节且性能更稳。

为什么Sunday比KMP更适合内存特征码搜索
内存搜索场景下,Sunday算法通常比KMP更实用——不是因为它理论最优,而是它在真实二进制数据中跳得准、写得快、出错少。KMP的next数组依赖模式串内部重复结构,而内存特征码(比如"\x48\x8B\xC4\x48\x83\xEC\x20")往往无规律、无重复,此时next数组几乎全是0,KMP退化为暴力扫描;Sunday则不管模式串长什么样,只要预处理好shiftTable[256],每次失配都能跳过至少1字节,平均性能更稳。
Sunday预处理必须用unsigned char索引
常见错误是直接用char做数组下标:当特征码含\xFF这类高位为1的字节时,char会解释为-1,导致shiftTable[-1]越界或静默写错位置。正确做法是强制转成unsigned char:
void BuildShiftTable(const std::string& pattern, int shiftTable[256]) {
int len = pattern.length();
for (int i = 0; i < 256; ++i) shiftTable[i] = len + 1;
for (int i = 0; i < len; ++i)
shiftTable[(unsigned char)pattern[i]] = len - i; // 关键:这里必须强转
}- 不转会导致
pattern[i] == '\xFF'时访问shiftTable[255]还是shiftTable[-1]完全取决于编译器和平台 -
shiftTable大小固定为256,覆盖全部unsigned char取值范围 - 若模式串为空,
len == 0,循环不执行,所有项保持len + 1 == 1,后续匹配逻辑仍成立
KMP的next数组构造容易漏掉边界条件
手写KMP时,next[0] = 0是共识,但next[1]的计算常出错:当模式串前两个字符相等(如"AA"),next[1]应为1,而非0。错误实现会导致匹配指针卡死或漏匹配。标准写法要严格按定义来:
void ComputeNext(const std::string& pattern, int next[]) {
int len = pattern.length();
next[0] = 0;
for (int i = 1; i < len; ++i) {
int j = next[i - 1];
while (j > 0 && pattern[i] != pattern[j])
j = next[j - 1];
if (pattern[i] == pattern[j])
j++;
next[i] = j;
}
}- 循环内
while必须带j > 0判断,否则next[j-1]可能访问next[-1] - 最后一行
next[i] = j不能写成next[i] = j + 1,否则所有值偏移 - 对纯二进制特征码(含
\x00),std::string仍可安全存储,但需用.data()和.length(),勿用.c_str()
通配符支持必须改匹配主循环,不能只动预处理
加通配符(如'?'表示任意字节)时,有人试图在BuildShiftTable里跳过'?',这是无效的——Sunday的跳跃逻辑只看“窗口后下一个字符”,和通配符无关。真正要改的是匹配内层循环:
立即学习“C++免费学习笔记(深入)”;
bool match = true;
for (int j = 0; j < len; ++j) {
unsigned char c = (unsigned char)haystack[i + j];
unsigned char p = (unsigned char)pattern[j];
if (p != '?' && c != p) { // 关键:通配符在此处跳过比较
match = false;
break;
}
}- 预处理表仍照常构建,
'?'会被当作普通字符塞进表里,但不影响——它根本不会被查表 - 失配后跳跃逻辑不变:
i += shiftTable[(unsigned char)haystack[i + len]],哪怕haystack[i + len]是'?'也没关系 - 若通配符占比高(>30%),Sunday优势会减弱,此时应考虑Shift-And等位运算算法
真正难的不是选算法,而是确认你搜的那块内存有没有被ASLR偏移、有没有页保护、是否跨页边界——这些会让任何字符串算法返回-1,但原因跟算法本身毫无关系。



















