Python中的stringlib字符串查找算法是Boyer-Moore, Horspool, Sunday, Bloom Filter几种算法的合成体, 大概的原理如下:

def find(s, p):# find first occurrence of p in sn = len(s)m = len(p)skip = delta1(p)[p[m-1]]i = 0while i <= n-m:if s[i+m-1] == p[m-1]: # (boyer-moore)# potential matchif s[i:i+m-1] == p[:m-1]:return iif s[i+m] not in p:i = i + m + 1 # (sunday)else:i = i + skip # (horspool)else:# skipif s[i+m] not in p:i = i + m + 1 # (sunday)else:i = i + 1return -1 # not found

以下是具体实现:

/* stringlib: fastsearch implementation */#ifndef STRINGLIB_FASTSEARCH_H
#define STRINGLIB_FASTSEARCH_H#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>/* fast search/count implementation, based on a mix between boyer-moore and horspool, with a few more bells and whistles on the top.for some more background, see: http://effbot.org/zone/stringlib.htm *//* note: fastsearch may access s[n], which isn't a problem when usingPython's ordinary string types, but may cause problems if you'reusing this code in other contexts.  also, the count mode returns -1if there cannot possible be a match in the target string, and 0 ifit has actually checked for matches, but didn't find any.  callersbeware! */#define FAST_COUNT 0
#define FAST_SEARCH 1
#define FAST_RSEARCH 2#ifndef LONG_BIT
#define LONG_BIT 32
#endif#if LONG_BIT >= 128
#define STRINGLIB_BLOOM_WIDTH 128
#elif LONG_BIT >= 64
#define STRINGLIB_BLOOM_WIDTH 64
#elif LONG_BIT >= 32
#define STRINGLIB_BLOOM_WIDTH 32
#else
#error "LONG_BIT is smaller than 32"
#endif#define STRINGLIB_BLOOM_ADD(mask, ch) \((mask |= (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1)))))
#define STRINGLIB_BLOOM(mask, ch)     \((mask &  (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1)))))ssize_t fastsearch(const char *s, ssize_t n,const char *p, ssize_t m,ssize_t maxcount, int mode)
{unsigned long mask;ssize_t skip, count = 0;ssize_t i, j, mlast, w;w = n - m;if (w < 0 || (mode == FAST_COUNT && maxcount == 0)) {return -1;}/* look for special cases */if (m <= 1) {if (m <= 0) {return -1;}/* use special case for 1-character strings */if (mode == FAST_COUNT) {for (i = 0; i < n; i++)if (s[i] == p[0]) {count++;if (count == maxcount) {return maxcount;}}return count;}else if (mode == FAST_SEARCH) {for (i = 0; i < n; i++)if (s[i] == p[0]) {return i;}}else {      /* FAST_RSEARCH */for (i = n - 1; i > -1; i--)if (s[i] == p[0]) {return i;}}return -1;}mlast = m - 1;skip = mlast - 1;mask = 0;if (mode != FAST_RSEARCH) {/* create compressed boyer-moore delta 1 table *//* process pattern[:-1] */for (i = 0; i < mlast; i++) {STRINGLIB_BLOOM_ADD(mask, p[i]);if (p[i] == p[mlast]) {skip = mlast - i - 1;}}/* process pattern[-1] outside the loop */STRINGLIB_BLOOM_ADD(mask, p[mlast]);for (i = 0; i <= w; i++) {/* note: using mlast in the skip path slows things down on x86 */if (s[i + m - 1] == p[m - 1]) {/* candidate match */for (j = 0; j < mlast; j++)if (s[i + j] != p[j]) {break;}if (j == mlast) {/* got a match! */if (mode != FAST_COUNT) {return i;}count++;if (count == maxcount) {return maxcount;}i = i + mlast;continue;}/* miss: check if next character is part of pattern */if (!STRINGLIB_BLOOM(mask, s[i + m])) {i = i + m;}else {i = i + skip;}}else {/* skip: check if next character is part of pattern */if (!STRINGLIB_BLOOM(mask, s[i + m])) {i = i + m;}}}}else {      /* FAST_RSEARCH *//* create compressed boyer-moore delta 1 table *//* process pattern[0] outside the loop */STRINGLIB_BLOOM_ADD(mask, p[0]);/* process pattern[:0:-1] */for (i = mlast; i > 0; i--) {STRINGLIB_BLOOM_ADD(mask, p[i]);if (p[i] == p[0]) {skip = i - 1;}}for (i = w; i >= 0; i--) {if (s[i] == p[0]) {/* candidate match */for (j = mlast; j > 0; j--)if (s[i + j] != p[j]) {break;}if (j == 0)/* got a match! */{return i;}/* miss: check if previous character is part of pattern */if (!STRINGLIB_BLOOM(mask, s[i - 1])) {i = i - m;}else {i = i - skip;}}else {/* skip: check if previous character is part of pattern */if (!STRINGLIB_BLOOM(mask, s[i - 1])) {i = i - m;}}}}if (mode != FAST_COUNT) {return -1;}return count;
}#endif

测试代码

#include <arch/cycle.h>int main(int argc, char **argv)
{char *str = "GET / HTTP 1.0\r\nHost: www.xxx.com\r\nCache: \r\nCache:\r\n Length:\r\n";ssize_t rc = 0;uint64_t start, end;start = get_cycle_count();rc = fastsearch(str, strlen(str), "Cache:", 6, 2, FAST_SEARCH);end = get_cycle_count();printf("fastsearch return %u cost %llu \n", rc, end - start);printf("result = %s\n", str + rc);rc = fastsearch(str, strlen(str), "Cache:", 6, -1, FAST_COUNT);printf("result = %u\n", rc);return 0;
}

看stringlib测试数据, 还是蛮可以的.

我在tile平台上测试发现还没有snort中的BMH算法速度快.

不过这个只是单一测试, 没有考虑到cache的情况, 仅供参考.

原文参考:

The stringlib Library 有详细的描叙.

提取Python stringlib中的BMHBNFS字符串查找算法相关推荐

  1. 暴力子字符串查找算法

    暴力子字符串查找算法的名字虽然很霸气,但是效率不是很高.是一种简单.粗暴的查找方式. 在最坏的情况下,暴力子字符串查找算法在长度为N的文本中查找长度为M的模式需要~NM次字符比较. 核心思想:就是对主 ...

  2. python实现kd树以及最近邻查找算法

    python实现kd树以及最近邻查找算法 一.kd树简介 二.kd树生成 1.确定切分域 2.确定数据域 3.理解递归树 4.python实现递归树代码 三.kd树上的最近邻查找算法 1.生成搜索路径 ...

  3. Rabin-Karp 指纹字符串查找算法

    Rabin-Karp 指纹字符串查找算法 M.O.Rabin 和 R.A.Karp 发明了一种完全不同的基于散列的字符串查找算法.我们需要计算模式字符串的散列函数,然后用相同的散列函数计算文本中所有可 ...

  4. 基于中间代码的优化中,循环的查找算法有哪些?循环优化的方法有哪些?举例说明。

    基于中间代码的优化中,循环的查找算法有哪些?循环优化的方法有哪些?举例说明. 基于中间代码的优化中,循环的查找算法有哪些?循环优化的方法有哪些?举例说明. 西北工业大学编译原理课件第八章 代码优化.p ...

  5. python 提取文字段落中的日期字符串

    需求 在日常业务开发中常常会碰到需要从一段文字中提取时间的情况.例如从文字中提取发布时间.创建时间等.针对不同的文字情况.不同的时间格式,这里整理一份关于提取大部分文字段落中日期时间的代码.有需要的直 ...

  6. Python API快餐教程(1) - 字符串查找API

    摘要: 字符串查找API 字符串处理相关API 字符串是7种序列类型中的一种. 除了序列的操作函数,比如len()来求字符串长度之外,Python还为字符串提供丰富到可以写个编辑器的API. 查找类A ...

  7. python基础(一)字符串查找

    (2)字符串查找 .count() 功能:计算指定的字符在字符串里出现的次数有多少 格式:字符串.count(查找字符串[,开始索引[,结束索引]]) 返回值:整数 .find() 功能与index( ...

  8. 字符串查找算法BF、KMP详解

    字符串查找: BF算法: (朴素查找算法) 当查找不成功时,主串返回刚刚起始字符的下一个,子串返回第一个字符位置 时间复杂度:O(n*m) int BF(const char* str, const ...

  9. Rabin-Karp字符串查找算法学习:poj1200

    本来准备学习Hash的,结果看PPT讲的第一个算法竟然是跟字符串处理相关的,本来Hash中也有一块专门讲字符串Hash的,就按照<算法导论>中的分类,把这个分到"字符串处理&qu ...

  10. leetcode中关于使用二分查找算法思想deal的题型

    学习了二分查找的算法思想之后,再leetcode上写了一道常见的简单面试题,现在用博客记录一下我学习刷题的笔记! leetcode 题号69:Sqrt(x)(经典的面试题) 给你一个非负整数 x ,计 ...

最新文章

  1. 多线程:synchronize、volatile、Lock 的区别与用法
  2. Vue——定义全局工具类
  3. 9月第1周国内搜索类网站频道:百度覆盖数创新高
  4. 【LeetCode笔记】剑指 Offer 15-. 二进制中1的个数 (Java、位运算)
  5. covariance matrix r语言_时间序列分析|ARIMAX模型分步骤详解和R中实践
  6. STM32固件库文件分析
  7. PHP中如何防止直接访问或查看或下载config.php文件
  8. Jakarta EE 9 企业版本合规性
  9. SpringBoot结合ActiveMQ(同时支持Queue和Topic)
  10. ubuntu安装无线网卡驱动(Ralink)
  11. java导出excel水印_java实现导出带有水印的excel
  12. ZR1012 Zbox loves keyboard (dp)
  13. 【整理】TAC码是什么?TAC码和IMEI有什么关系?
  14. The MVGC Multivariate Granger Causality Matlab初上手记录
  15. Java培训机构哪个好?该怎么选择
  16. 雷锋网特约专访易科成志创始人、CEO潘真
  17. 计算任意文件夹大小 , 校验大文件的一致性 , 发抢红包程序
  18. 成人高等教育本科生学士学位日语水平考试大纲
  19. python写入中文json
  20. java 线框图_十个完全免费的网页原型(线框图)工具

热门文章

  1. mysql对库授权alter_mysql 权限 alter update insert
  2. Luogu1894[USACO4.2] 完美的牛栏The Perfect Stall
  3. HDU5234 Happy birthday
  4. [图论] 树剖LCA
  5. POJ2187 Beauty Contest
  6. lvremove 删除逻辑卷
  7. wall 广播发送信息给所有user
  8. redis类型 tp5_tp5配置使用redis笔记!
  9. java 观察者模式_观察者模式(Observer Pattern)
  10. java string to bit_Java Convert String to Binary