hyperscan使用教程

目录

文档说明

关键词

hyperscan介绍

块模式(Block Mode)

流模式(Streaming Mode)

向量模式(Vectored Mode)

hyperscan使用

运行环境

安装

主要接口详解

示例详解

知识点

相关资源

源码位置

接口介绍等

性能测试


文档说明

本文介绍的hyperscan主要能帮你解决以下问题:

(1)在一个字符串(连续的内存单元)中高速查找是否有一个字符串集中的一个或多个字符串;

(2)在一个字符串(不连续的内存单元)中高速查找是否有一个字符串集中的一个或多个字符串;

(3)在一个持续的流中高速查找是否有一个字符串集中的一个或多个字符串;

        典型的持续流,如:不断提交上来的网络数据包,字符串集中的字符串可能被分割在不同的数据包中。

hyperscan匹配速率:是pcre的数十倍,数据吞吐率能到>10Gbps,甚至能>100Gbps.

关键词

        多模匹配、多模式匹配、单模匹配、单模式匹配、流式匹配、自动机、自动状态机、AC( Aho-Corasick)自动机、BM(Boyer-Moore)算法、正则匹配、正则表达式。

hyperscan介绍

        hyperscan是intel推出的一款高性能正则表达式引擎,基于X86平台以PCRE为原型而开发,支持PCRE的大部分语法,用c语言开发,提供一套 C API 。

跟pcre区别:

        (1)hyperscan匹配速率是pcre的数十倍;

        (2)hyperscan支持多模式匹配,不像pcre只支持单条的正则表达式的匹配。

hyperscan支持多种匹配模式:块模式、流模式、向量模式。

块模式(Block Mode)

        对一段完整的数据块进行扫描匹配,扫描匹配结束即返回最终结果,也即所有匹配的结果都在该段完整的数据块中,匹配结果不跨数据块,是一种传统的匹配模式。

块模式在所有模式中,消耗资源最小,匹配效率最高。

流模式(Streaming Mode)

        当扫描的结果不在一段完整的数据块中时,如在在真实网络场景下,数据是分散在持续不断过来的数据包中的,我们叫它数据流,扫描的结果往往会跨数据包,在不同的数据包中都有自己的一部分。这时要匹配到正确的结果,如果用传统的匹配思路,可以把所有数据全部缓存下来,最终来一次匹配。但是这样的话不仅会增加内存的开销,还会使得匹配没有了实时性,因为数据流可能会持续很长的一段时间。

        Hyperscan的流模式,专门设计为对这种流数据的匹配。通过有限量的流内存对流匹配信息进行记录,在不缓存已过去流数据的情况下,保证能正确地匹配出所有结果,同时也不会有匹配不实时的问题。

向量模式(Vectored Mode)

向量模式适用以下场景:

(1)不是对一段完整的数据块进行扫描匹配,要扫描匹配的数据块分散在多个不连续的内存块中;

(2)这些不连续的数据,也不像流数据在时间上有到来的先后,而是在扫描前用户就能全部准备好。

hyperscan使用

运行环境

        hyperscan只能在x86平台上运行。

安装

        以下安装过程基于linux(centos)。

主要依赖安装

ragel安装

源码下载地址:

Ragel State Machine Compilerhttp://www.colm.net/open-source/ragel/

本次安装版本为:ragel-6.10.tar.gz

安装过程:

$ tar -xvf ragel-6.10.tar.gz    //解压

$ cd ragel-6.10

$ ./configure

$ make

$ sudo make install

$ ldconfig // 让动态链接库为系统所共享

boost安装

源码下载地址:

Boost C++ Libraries - Browse /boost at SourceForge.netFree peer-reviewed portable C++ source librarieshttps://sourceforge.net/projects/boost/files/boost

本次安装版本为:boost_1_69_0

安装过程:

$ tar -xvf  boost_1_69_0.tar.gz     // 解压

$ cd boost_1_69_0

$ ./bootstrap.sh

$ sudo ./b2 --with-iostreams --with-random install  // 只安装iostreams和random,当然也可以完整安装,安装过程会比较慢

$ ldconfig // 让动态链接库为系统所共享

hyperscan安装

源码下载地址:

Releases · intel/hyperscan · GitHubHigh-performance regular expression matching library - Releases · intel/hyperscanhttps://github.com/intel/hyperscan/releases

本次安装版本为:hyperscan-5.1.0

安装过程:

$ tar -xvf hyperscan-5.1.0.tar.gz

$ cd hyperscan-5.1.0

$ mkdir cmake-build

$ cd cmake-build

$ cmake -DBUILD_SHARED_LIBS=on -DCMAKE_BUILD_TYPE=Release ..

$ make -j8    // 多线程加速编译

$ sudo make install

$ ldconfig  // 让动态链接库为系统所共享

主要接口详解

从使用角度上介绍各匹配模式的主要接口,其他接口详见“相关资源”->“接口介绍等”。

块模式主要接口

(1)正则表达式编译函数

hs_error_t hs_compile(const char *expression, unsigned int flags, unsigned int mode, const hs_platform_info_t *platform, hs_database_t **db, hs_compile_error_t **error)

//单模正则匹配编译函数

expression要被编译的正则表达式,也即搜索字符串集;

flags:表达式行为的标志,如:是否大小写敏感(HS_FLAG_CASELESS

)等,具体可参看hyperscan源码中的 hs_compile.h 文件;

mode数据库匹配模式标志:

HS_MODE_BLOCK :块模式

HS_MODE_STREAM  :流模式

HS_MODE_VECTORED :向量模式

platform确定数据库的目标平台,一般写NULL,表示生成适合在当前主机平台上运行的数据库;

db指向最终编译成的模式数据库指针;

error错误返回,出错是,需用 hs_free_compile_error () 函数释放该缓冲区;

hs_error_t hs_compile_multi(const char *const *expressions, const unsigned int *flags, const unsigned int *ids, unsigned int elements, unsigned int mode, const hs_platform_info_t *platform, hs_database_t **db, hs_compile_error_t **error)

//多模正则匹配编译函数

expressions:指针数据,用于存储多个匹配表达式(pcre也是单模,一次只能编译一条正则表达式),不同于hs_compile函数的expression,是一个字符串指针;

(2)分配草稿空间

hs_error_t hs_alloc_scratch( const hs_database_t * db , hs_scratch_t ** scratch )

db:编译函数生成的数据库,如上面hs_compile生成的db;

scratch:指向草稿空间指针,用于返回分配的草稿空间;

(3)块扫描函数

hs_error_t hs_scan( const hs_database_t * db , const char * data , unsigned int length , unsigned int flags , hs_scratch_t * scratch , match_event_handler onEvent , void * context )

db:编译函数生成的数据库,如上面的hs_compile;

data:指向被扫描数据的指针;

length:被扫描数据的长度;

flags:预留,暂未使用;

scratch:数据库草稿空间,多线程检测时,每个检测线程都需要自己独立的草稿空间;

onEvent:匹配时间的回调函数,每触发一次匹配将调用一次改回调函数;

context:指向用户自定义数据,用于onEvent函数做响应的结果返回;

(4)释放草稿空间

hs_error_t hs_free_scratch(hs_scratch_t *scratch)

scratch指向将被释放的草稿空间;

(5)释放编译数据库

hs_error_t hs_free_database(hs_database_t *db)

db指向将被释放的模式数据库,如上面hs_compile生成的db;

流模式主要接口

主要流程参看,块模式,这里只列出之间的差异。

(1)正则表达式编译函数

(2)分配草稿空间

(3)打开数据流

hs_error_t hs_open_stream( const hs_database_t * db , unsigned int flags , hs_stream_t ** stream )

db编译函数生成的数据库;

flags预留,暂未使用;

stream指向该函数生成的数据流;

(4)流扫描函数

hs_error_t hs_scan_stream( hs_stream_t * id , const char * data , unsigned int length , unsigned int flags , hs_scratch_t * scratch , match_event_handler onEvent , void * ctxt )

id hs_open_stream 函数放回的数据流;

其他参数同块模式的块扫描函数。

(5)释放草稿空间

(6)关闭数据流

hs_error_t hs_close_stream( hs_stream_t * id , hs_scratch_t * scratch , match_event_handler onEvent , void * ctxt )

idhs_open_stream 函数放回的数据流;

scratch由 hs_alloc_scratch () 分配的草稿空间。仅当 onEvent 回调也是 NULL 时才允许为 NULL;

onEvent指向匹配事件回调函数的指针。如果为 NULL 指针,则不会返回匹配结果;

ctxt指向用户自定义数据,用于匹配发生时返回结果;

(7)释放编译的数据库

向量模式主要接口

主要流程参看块模式,这里只列出之间的差异。

(1)正则表达式编译函数

(2)分配草稿空间

(3)向量扫描函数

hs_error_t hs_scan_vector( const hs_database_t * db , const char * const * data , const unsigned int * length , unsigned int count , unsigned int flags , hs_scratch_t * scratch , match_event_handler onEvent , void * context )

data:指针数组,指向要扫描数据;

length:对应指针数组,每个指针指向数据的大小;

count:data指针数组的大小,也即数组length的大小;

其他参数上面的其他接口函数。

(4)释放草稿空间

(5)释放编译的数据库

示例详解

块扫描

hyperscan源码的示例,位置:

        examples/simplegrep.c

示例功能简介:

        块模式匹配,运行参数argv[1]提供扫描串编译生成模式数据库,运行参数argv[2]为一个文件,文件内容为被扫描数据。

流扫描示例

hyperscan源码的示例,位置:

        examples/pcapscan.cc

示例功能简介:

        通过读取pcap文件(pcap文件可通过一些网络工具,如wireshark捕获数据包生成的文件),模拟实际网络环境做流模式匹配。

知识点

(1)做多线程匹配时,每个线程都需要有自己独立的草稿空间,分别调用hs_clone_scratch 和hs_free_scratch做对应的克隆和释放;

(2)匹配结果,为效率考虑,只提供匹配结果在被匹配字符串结束位置(即to:相对于字符串开始的偏移位置),匹配的回调函数:

int match_event_handler(unsigned int id, unsigned long long from, unsigned long long to, unsigned int flags, void *context )

要想得到起始位置from,在编译模式数据库时,需在对应的表达式上加上flag标志:HS_FLAG_SOM_LEFTMOST。

(3)流式匹配要想获得匹配的起始位置from,除了(2)中加上对应的flag标志外,还需在编译时加上特定mode标志,即下三个中的一个:

/**
 * Compiler mode flag: use full precision to track start of match offsets in
 * stream state.
 *
 * This mode will use the most stream state per pattern, but will always return
 * an accurate start of match offset regardless of how far back in the past it
 * was found.
 *
 * One of the SOM_HORIZON modes must be selected to use the @ref
 * HS_FLAG_SOM_LEFTMOST expression flag.
 */
#define HS_MODE_SOM_HORIZON_LARGE   (1U << 24)

/**
 * Compiler mode flag: use medium precision to track start of match offsets in
 * stream state.
 *
 * This mode will use less stream state than @ref HS_MODE_SOM_HORIZON_LARGE and
 * will limit start of match accuracy to offsets within 2^32 bytes of the
 * end of match offset reported.
 *
 * One of the SOM_HORIZON modes must be selected to use the @ref
 * HS_FLAG_SOM_LEFTMOST expression flag.
 */
#define HS_MODE_SOM_HORIZON_MEDIUM  (1U << 25)

/**
 * Compiler mode flag: use limited precision to track start of match offsets in
 * stream state.
 *
 * This mode will use less stream state than @ref HS_MODE_SOM_HORIZON_LARGE and
 * will limit start of match accuracy to offsets within 2^16 bytes of the
 * end of match offset reported.
 *
 * One of the SOM_HORIZON modes must be selected to use the @ref
 * HS_FLAG_SOM_LEFTMOST expression flag.
 */
#define HS_MODE_SOM_HORIZON_SMALL   (1U << 26)

相关资源

源码位置

Releases · intel/hyperscan · GitHubHigh-performance regular expression matching library - Releases · intel/hyperscanhttps://github.com/intel/hyperscan/releases

接口介绍等

官方英文资料

http://intel.github.io/hyperscan/dev-reference/api_files.html#file-hs-h

hyperscan_sys - RustHyperscan is a software regular expression matching engine designed with high performance and flexibility in mind.https://docs.rs/hyperscan-sys/0.2.1/hyperscan_sys/

翻译很好的中文资料

section2--hyperscan 的对应接口 - 高性能正则 - 计算机科学 | Echidna = Echidna 的小窝 = l am the bone of my swordhttp://www.echidna-sxh.com/hyperscan/hyperscan-api/

性能测试

【ClickHouse为什么这么快?】3. 正则匹配算法 re 和 hyperscan 介绍_51CTO博客_clickhouse正则匹配查询【ClickHouse为什么这么快?】3. 正则匹配算法 re 和 hyperscan 介绍,一、什么是正则表达式?如何匹配特定的字符串?为了解决这个问题,定义一淘描述字符串特征的的模式,用于查找、替换符合特征的字符串,或者用来验证某个字符串是否符合指定的特征——这个模式就是“正则表达式”。正则表达式最初的想法源于1940年,神经生理学家WaarrenMcCulloch与WalterPitts研究出了一种用数而简单的自...https://blog.51cto.com/u_15236724/5365574

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要使用 Hyperscan 来检测域名的合法性,您需要先安装 Hyperscan 库,并编写相应的代码来进行匹配。以下是一个简单的示例代码,演示如何使用 Hyperscan 来检测域名的合法性: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <hs/hs.h> int main() { char domain[100]; printf("请输入一个域名:"); scanf("%s", domain); // 编译正则表达式 const char* pattern = "^[a-zA-Z0-9]+([\\-\\.][a-zA-Z0-9]+)*\\.[a-zA-Z]{2,}([a-zA-Z0-9]*)$"; hs_database_t* database; hs_compile_error_t* compile_err; if (hs_compile(pattern, HS_FLAG_CASELESS, HS_MODE_BLOCK, NULL, &database, &compile_err) != HS_SUCCESS) { fprintf(stderr, "无法编译正则表达式:%s\n", compile_err->message); hs_free_compile_error(compile_err); exit(1); } // 创建匹配数据库 hs_scratch_t* scratch; if (hs_alloc_scratch(database, &scratch) != HS_SUCCESS) { fprintf(stderr, "无法创建匹配数据库\n"); hs_free_database(database); exit(1); } // 进行匹配 if (hs_scan(database, domain, strlen(domain), 0, scratch, NULL, NULL) == HS_SUCCESS) { printf("域名合法\n"); } else { printf("域名非法\n"); } // 释放资源 hs_free_scratch(scratch); hs_free_database(database); return 0; } ``` 此示例代码使用 Hyperscan 库中的函数来编译正则表达式,创建匹配数据库,并进行域名的匹配。正则表达式模式与之前的示例相同,用于匹配域名的格式。 请注意,为了使用 Hyperscan 库,您需要先下载和安装 Hyperscan。您可以从 Hyperscan 的官方网站获取最新版本的库文件和开发文档。在编译时,还需要将 Hyperscan 的头文件和库文件正确地链接到您的项目中。 此外,Hyperscan 是一款用于高性能多模式字符串匹配的库,其设计目标是在大规模数据流中实现快速匹配。在仅进行域名合法性检测的场景下,Hyperscan 可能会过于强大。如果仅需简单的正则表达式匹配,使用其他轻量级的正则表达式库可能更合适。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhjuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值