百倍正则加速:让Yak中的正则支持统一编译与完整PCRE2

admin 2026-07-11 04:43:17 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: Yak项目通过go-pcre2-lite和minirehs两项自研工作重做正则路径,将单条正则引擎替换为完整PCRE2并实现多正则统一编译一次扫描。在YakitMITM场景中,真实规则集吞吐从0.19MB/s提升至6.10MB/s(32倍),合成集加速比随规则数增长(50条时11.6倍,1000条时83.6倍)。解决了语法能力不足、回溯不可控、匹配成本线性增长和内存开销偏高等问题。建议类似场景采用此架构优化性能。 综合评分: 86 文章分类: 安全工具


cover_image

百倍正则加速:让 Yak 中的正则支持统一编译与完整 PCRE2

原创

YAK YAK

Yak Project

2026年7月10日 17:26 湖南

在小说阅读器读本章

去阅读

两项自研工作重做 Yaklang / Yakit 的正则路径:go-pcre2-lite 将单条正则引擎替换为完整 PCRE2,minirehs/rehs 让成百上千条正则支持”统一编译、一次扫描”。

前者降低单条匹配的成本并扩展可编译范围,后者将多正则的复杂度由乘性转为加性——两者在 Yakit MITM 内置规则场景中叠加生效。

除特别标注外,性能数字为本机(darwin/arm64, Apple Silicon)第一手实测;图 3 左半为 go-pcre2-lite 仓库自带基准。

图三

摘要

Yakit MITM 会在每一条经过的报文上执行一批内置规则(指纹识别、组件染色、敏感信息提取)。旧路径存在两个长期问题:

其一是正则语法能力不足——标准库 RE2 不支持 lookaround/backreference,大量从 JS/PHP/.NET 移植的正则直接编译失败,而兜底引擎默认永不超时,单条异常正则即可导致代理无响应;其二是成本随规则数线性增长——数十至上百条正则对每条报文逐条全量匹配,成本为”规则数 × 报文字节”的乘积。

本次改造从两层同时入手:单条正则层采用 go-pcre2-lite(完整 PCRE2、JIT 关闭、dlclark/regexp2 的 drop-in 替代,布尔匹配零分配、ReDoS 默认有界、语法更全);多正则层采用 minirehs 将所有规则统一编译为单一引擎,每条报文仅扫描一次。

在真实 MITM 规则集(87 条)+ 真实流量(~5MB / 1332 报文)上,存在性打标由现状 0.19 MB/s 提升至 6.10 MB/s(约 32×);在字面量友好的合成集上,加速比随规则数从 50 条的 11.6× 增长至 1000 条的 83.6×

改造前后速览(数据来源见后文对应章节):

| | | | | — | — | — | | 维度 | 改造前 | 改造后 | | 正则语法 | 仅 RE2,lookaround/backref 编译失败 | RE2 + 完整 PCRE2(原子组、递归、\K、子程序、Unicode 属性) | | ReDoS 安全 | 默认永不超时,可持续回溯挂起 | match/depth 限额有界,超限返回 ErrMatchLimit | | 布尔匹配分配 | 每次匹配复制整段为 []rune | 热路径 0 B / 0 allocs | | 单条匹配速度 | 基线(dlclark/regexp2) | 1.8×–9.6×(vs dlclark,库自带基准) | | 多正则复杂度 | O(N_rules × N_bytes) 逐条 | ~O(N_bytes) 一次扫描 | | MITM 真实吞吐(87 规则 / ~5MB) | 0.19 MB/s | 6.10 MB/s(32×) | | 规则数放大(合成集,N=1000) | 2.78 MB/s | 232 MB/s(83.6×) |

一、背景与问题:Yakit 旧时代的正则困境

Yakit MITM 长期存在的正则相关问题可归纳为四类:

  • 语法能力受限:MITM 默认使用标准库 RE2。RE2 为保证线性时间复杂度,不支持 lookaround、backreference 等构造。从 JS/PHP/.NET 项目移植的正则常因此编译失败,只能改写或弃用。
  • 回溯不可控:RE2 无法表达的规则回退到 dlclark/regexp2,该引擎默认 MatchTimeout = 永不超时;对抗性正则遇到构造性输入时会持续回溯直至挂起,表现为 CPU 占满、代理无响应。
  • 匹配成本随规则数线性增长:MITM 内置数十条规则,实现为”对每条报文将每条正则各匹配一次”。报文体积与规则数增大时吞吐显著下降,这是”多正则一次匹配随规模劣化”的根因。
  • 内存开销偏高dlclark 在匹配热路径上每次都将整段输入复制为 []rune,长时间运行时 GC 压力较大。

上述问题在真实规则集上并非均匀分布,而是集中于少数规则。以 rule4yak 87 条内置规则为例,其中含 lookahead 的 URL 识别类规则在 RE2 下直接编译失败,旧路径只能整体回退到 dlclark/regexp2 并对每条报文全量执行;这类 regexp2-only 规则仅约 2–3 条,却在切换前贡献了定位路径约 35% 的 CPU 与约 74% 的分配getRunes 的整段 []rune 复制)。即少量重规则主导了整体开销。

将上述问题归结为成本模型,MITM 染色/提取的总成本为:

```
总成本 ≈ N_packets × N_rules × 单条正则匹配成本
由此可得两条正交的优化路径:**降低单条正则匹配成本**,以及**消除****`× N_rules`****这一乘性因子**。前者属于引擎层面(语法能力、速度、内存、ReDoS 安全),后者属于复杂度层面(避免对每条报文逐条匹配 N 条规则)。二者分别由go-pcre2-lite 与 `minirehs` 承担,互不替代、可叠加。

本文以实测数据回答四个问题:改造后的实际吞吐、对正则本身的影响、规则数增大时的加速表现、以及对 Yak Project 整体技术体系的影响。

**二、方法与实现:完整 PCRE2 与统一编译**

整体结构为"单条正则引擎"之上叠加一层"多正则批量调度",再接入 MITM 的染色/提取路径:
flowchart TB&nbsp; &nbsp; MITM["Yakit MITM 染色 / 指纹 / 提取"]&nbsp;--> L2&nbsp; &nbsp; subgraph L2["多正则批量层 · minirehs / rehs"]&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;direction&nbsp;TB&nbsp; &nbsp; &nbsp; &nbsp; C["统一编译<br/>所有规则 → 一个不可变 Database"]&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;P["字面量预过滤<br/>Aho-Corasick / bit-NFA 一次扫描"]&nbsp; &nbsp; &nbsp; &nbsp; V["候选验证<br/>只对命中候选跑正则"]&nbsp; &nbsp; &nbsp; &nbsp; C -->&nbsp;P&nbsp;--> V&nbsp; &nbsp; end&nbsp; &nbsp; subgraph L1["单条正则引擎层 · go-pcre2-lite"]&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;direction&nbsp;TB&nbsp; &nbsp; &nbsp; &nbsp; RE2["RE2 可表达 → 标准库 regexp(线性)"]&nbsp; &nbsp; &nbsp; &nbsp; PCRE["RE2 不可表达 → 完整 PCRE2 兜底<br/>(lookaround/backref, 零分配, ReDoS 有界)"]&nbsp; &nbsp; end&nbsp; &nbsp; V -. "候选命中后精确判定"&nbsp;.-> L1&nbsp; &nbsp; L1 -->&nbsp;R["命中规则集合 / 精确偏移"]
两层分工明确:`minirehs`&nbsp;决定"**对哪些规则、在哪些位置**执行正则验证",`go-pcre2-lite`&nbsp;决定"**每一次验证的速度、安全性与可编译性**"。

***YAK***

**2.1 单条正则层:`go-pcre2-lite`(完整 PCRE2)**

### 它是&nbsp;`github.com/dlclark/regexp2`&nbsp;的 drop-in 替代,绝大多数代码只改一行

import:// beforeimport “github.com/dlclark/regexp2″// afterimport regexp2 “github.com/VillanCh/go-pcre2-lite/regexp2”

实现要点:

* **完整 PCRE2 8-bit 解释器**,C 源码随仓库 vendored、经 cgo 编入,**JIT 永久关闭**(分发稳定、无运行期代码生成风险)。
* **drop-in 兼容**:类型、方法、`RegexOptions`、rune 索引的&nbsp;`Index`/`Length`、`Replace`/`ReplaceFunc`、`Escape`&nbsp;都对齐&nbsp;`regexp2`;在 PCRE2 官方 testoutput1 语料的 1585 条输入上,整段匹配结果与 dlclark100% 一致。
* **语法更全**:possessive 量词&nbsp;`a++`、原子组&nbsp;`(?>…)`、递归&nbsp;`(?R)`、`\K`、子程序&nbsp;`(?&name)`、Unicode 属性——这些 dlclark 直接拒绝的构造均可编译,覆盖背景中"语法能力受限"一类此前无法运行的规则。
* **ReDoS 默认有界**:由 PCRE2 的 match/depth 限额兜底,`(a+)+$`&nbsp;这类指数回溯返回&nbsp;`ErrMatchLimit`&nbsp;而非挂起;收紧 SetMatchLimits 后可将攻击压至亚毫秒,对应背景中"回溯不可控"导致的代理无响应。库自带用例覆盖 moment.jsCVE-2022-31129、UAParser.js CVE-2020-7733 等真实 ReDoS,均可终止。

在 Yaklang 里,正则统一走&nbsp;`common/utils/regexp-utils`&nbsp;的&nbsp;`NewYakRegexpUtils(...)`:优先标准库 RE2(线性无回溯),RE2 编译失败时回退 PCRE2 兜底。切换后&nbsp;`regexp-utils.go`&nbsp;与 MITM 预过滤模块的 import 已统一指向&nbsp;`go-pcre2-lite/regexp2`。

***YAK***

**2.2 多正则层:`minirehs`(yak 语言里注册为&nbsp;`rehs`)**

`minirehs`&nbsp;是一个**零外部依赖、可移植**的多正则批量匹配引擎,借鉴 Intel Hyperscan 的"统一编译、一次扫描"模型:
// yak 语言里以 rehs 库暴露:一行编译、一次扫描判定哪些正则命中group&nbsp;= rehs.BuildGroup(["admin",&nbsp;"(?i)password",&nbsp;"token=\\w+"])~if&nbsp;group.Match(data) {&nbsp;/* 是否有任意命中,命中即停,最快 */&nbsp;}for&nbsp;m&nbsp;in&nbsp;group.Find(data) { println(m.Index, m.Pattern, m.From, m.To, m.Value) }
核心流程是**字面量提取 → Aho-Corasick / bit-NFA 预过滤(一次扫描,含位置)→ 候选邻域验证**。它按环境自动分档:

CGO 可用时默认下沉自带的纯 C99 位并行内核(最强档,**不链接、不 dlopen 任何外部库**),不可用时优雅退化为纯 Go,参考执行器,两档结果**逐字节一致**。

***YAK***

**2.3 接入 MITM:一个"绝不漏报"的统一预过滤**

接入点是&nbsp;`mitmRulePrefilter`(见&nbsp;`common/yakgrpc/yakit/httpflow_replacer_prefilter.go`):把所有可被 RE2 自动机

* 必需字面量安全门控的规则**一次性编译进一个常驻 Group**,每条报文只扫一次得到"候选位图",其余规则直接跳过昂贵的逐条匹配。作为安全工具,不漏报是底线,因此正确性由构造保证。

* 只有 "RE2 可精确表达且含必需字面量" 的规则(disposition=`primary`)才进入"可跳过集合";`regexp2-only`(lookaround/backref)或无必需字面量的规则一律标记为&nbsp;always-candidate(永不跳过)。

* 预过滤引擎强制开&nbsp;`Multiline`&nbsp;+&nbsp;`DotAll`,即**预过滤语言是规则语言的超集**——只会多报候选,绝不把真正会命中的报文判为不命中。

* 命中与否最终仍由原正则在候选规则上**精确判定**,染色/提取语义完全不变。

此外提供一键回退开关&nbsp;`YAKIT_MITM_REPLACER_DISABLE_PREFILTER=1`,可随时退回逐条匹配的旧行为,用于 A/B 对比或异常时紧急回退。

**三、实验设计**

##

|  |  |
| --- | --- |
| 维度 | 说明 |
| 硬件 / 系统 | darwin/arm64,Apple Silicon |
| Go 构建 | `CGO_ENABLED=1`,默认后端(纯 Go MVS + PCRE2 兜底,未加&nbsp;`minirehs_mvs`&nbsp;C 内核 tag) |
| 真实规则集 | rule4yak 87 条 MITM replacer 规则(`common/minirehs/testdata/rules.json`) |
| 真实语料 | 从本地 yaklang 项目库抽取的 ~5MB 真实 HTTP 流量(1332 报文,`traffic_corpus.bin`) |
| 合成集 | 固定 ~1MB 语料(256 × 4KB 报文),字面量丰富、命中稀疏,N ∈ {50,100,300,500,1000} |
| 口径 | 三后端共用**同一语料、同一规则、同一****`Scan`****API**;`b.SetBytes(语料字节)`&nbsp;→ MB/s 为聚合真吞吐;`benchtime=3x` |
| 基线 | **StdlibLoop**:N 条正则逐条扫整段,即"几百正则一次匹配"的等价现状 |

> 正确性不掺进吞吐判断:命中集合/偏移由独立差分测试保证(MVS 命中集与 stdlib oracle 逐字节一致、C 内核与 Go 参考执行器逐位一致)。

**四、Benchmark 结果**

这批规则的作用是对流量进行自动染色标注:例如报文中出现&nbsp;`rememberMe=`&nbsp;标注&nbsp;`组件-Shiro`、出现&nbsp;`swagger-ui.html标注``组件-Swagger指纹`、匹配&nbsp;`(?i)Druid`&nbsp;标注&nbsp;`组件-Druid`。**每一条流量都需经过整批规则匹配**,因此该路径的吞吐直接决定 MITM 启用规则后的处理能力。以下从复杂度、真实场景、引擎本身三个维度给出实测结果。

***YAK***

**4.1 复杂度:加速比随规则数增长(N=50 时 11.6× → N=1000 时 83.6×)**

固定 ~1MB 语料,仅改变正则条数 N。`minirehs`&nbsp;采用"一次扫描",吞吐**基本与 N 无关**(597→232 MB/s,缓降源于候选管理开销);逐条匹配的 StdlibLoop 随 N&nbsp;**线性劣化**(52→2.8 MB/s);二者比值即加速比,随 N 单调放大。

![](https://mmbiz.qpic.cn/mmbiz_png/jibGAup6p72Gl4ib5UW5CwGjoTbXzJ4CrfCwkiaYZ8Y2TJfu5bvPzG14OlLhNkS3micgCFuP0F250XTed6M8ZKiaUMNibfFtgZZudUGEaIIXYvwV0/640?wx_fmt=png&from=appmsg#imgIndex=16)

图一

|  |  |  |  |
| --- | --- | --- | --- |
| N | Engine 吞吐 | StdlibLoop 吞吐 | 加速比 |
| 50 | 597.40 MB/s | 51.53 MB/s | 11.6× |
| 100 | 511.08 MB/s | 26.25 MB/s | 19.5× |
| 300 | 411.14 MB/s | 9.20 MB/s | 44.7× |
| 500 | 327.55 MB/s | 5.56 MB/s | 58.9× |
| 1000 | 232.42 MB/s | 2.78 MB/s | 83.6× |

适用范围:指纹识别、扫描规则、IOC 匹配等字面量丰富、命中稀疏的场景,规则数越大收益越显著。

***YAK***

**4.2 真实 MITM 场景:0.19 → 6.10 MB/s(约 32×)**

本组为最接近 Yakit 实际的场景:87 条真实规则、~5MB 真实流量、同一&nbsp;`Scan`&nbsp;API 端到端。以现状 StdlibLoop(0.19 MB/s)为 1× 基线:

![](https://mmbiz.qpic.cn/mmbiz_png/jibGAup6p72ELDtnkKFYLgU5HtJraMFkJbDe94T1aQ61cpibBR7KaBfiaSsOga1Nq8PXYFDSgThKoKQaSib0vrA40ibRIBzcmdG8Haf3iau9ac7hY/640?wx_fmt=png&from=appmsg#imgIndex=17)

图二

|  |  |  |  |  |
| --- | --- | --- | --- | --- |
| 方案 | 吞吐 | 相对 StdlibLoop | allocs/op | 语义 |
| StdlibLoop(现状:逐条全量) | 0.19 MB/s | 1.0× | 2687 | 精确偏移 |
| Engine(纯 Go 字面量预过滤) | 0.47 MB/s | 2.5× | 4668 | 精确偏移 |
| MVS 定位档 | 2.66 MB/s | 14.0× | 357 | 精确偏移 |
| **MVS 存在性档** | **6.10 MB/s** | **32.1×** | 545 | 存在性 |
| **MVS 存在性(纯 RE2 子集)** | **7.18 MB/s** | **37.8×** | 423 | 存在性 |

> 口径说明:MVS 各档来自&nbsp;`BenchmarkMVSExistence`(87 条),Engine/StdlibLoop 来自&nbsp;`BenchmarkMITMRealTraffic`(RE2 可编译子集),两个基准共用同一 0.17~0.19 MB/s 的 StdlibLoop 固定参照。
>
> **存在性档不给精确偏移**(`From/To=-1`),契合 MITM 打标"只要哪些规则命中"的场景;需要替换/抽取的精确位置时用定位档。

折算为可感知延迟:按同一 per-byte 速率,处理一条 1 MB 的响应体(如 JS bundle、JSON 导出),逐条匹配约需&nbsp;**5.3 s**,存在性档降至约&nbsp;**0.16 s**——这是"MITM 开启全部内置规则后是否卡顿"的直接来源。打标仅判存在性时端到端约&nbsp;**32×**,纯 RE2 子集约&nbsp;**38×**,需要精确偏移的定位档亦达&nbsp;**14×**。

***YAK***

**4.3 引擎层面:单条 1.8×–9.6×,布尔匹配零分配**

左图为&nbsp;`go-pcre2-lite`(drop-in 层)相对&nbsp;`dlclark/regexp2`&nbsp;的单条加速比(库自带基准,darwin/arm64):各场景均更快,布尔匹配短串&nbsp;**9.6×**、100KB&nbsp;**9.3×**,且布尔匹配路径**零分配**。右图为将 minirehs 候选命中后的兜底引擎由 regexp2 更换为 PCRE2后,对 MVS 存在性吞吐的影响。

![](https://mmbiz.qpic.cn/mmbiz_png/jibGAup6p72HNksMVu3olyS0ibHcHUdhwicQ8oCk9nhIOCH9lfRk1DOpIWsCbhJsb1CmHbY2z1JbcIjynmibRy7nauybq87Bic5Na5QUco7UXxdw/640?wx_fmt=png&from=appmsg#imgIndex=18)

图三

|  |  |  |  |  |
| --- | --- | --- | --- | --- |
| 场景 | dlclark | pcre2 drop-in | 加速比 | drop-in 分配 |
| 布尔匹配·短串 | 6472 ns | 676 ns | 9.6× | **0 B / 0** |
| 布尔匹配·100KB | 26.4 ms | 2.84 ms | 9.3× | **0 B / 0** |
| 含反向引用 | 396 ns | 186 ns | 2.1× | **0 B / 0** |
| 重回溯·32KB | 20.0 ms | 10.9 ms | 1.8× | **0 B / 0** |
| 编译·复杂模式 | 10.3 µs | ~3.2 µs | 3.3× | 1.5 KB / 17 |
| FindAll·670 命中 | 380 µs | 138 µs | 2.8×(low-level 6.0×) | — |

> 右图**诚实标注**:"切换前"为 README 记录的 Phase 4 快照(C 内核存在性档),"切换后"为本机第一手实测(当前默认构建,纯 Go MVS + PCRE2 兜底),
>
> 两者后端档位不完全一致,**不是同一构建上的受控 A/B**,表达的是"当前默认构建相对历史快照的整体提升",其中兜底换 PCRE2 是被 profile 标记的主导因素之一,
>
> 但不能把全部增益单独归因于它;单条正则层的严格受控收益以左图 PCRE2 vs dlclark 为准。本机快速抽样(`benchtime=2x`,有噪声)也佐证了方向:短串布尔匹配 low-level ~9.5×、分配 5→1。

五、结果解释

* **合成集可达 80×+ 而真实 MITM 约 32× 的原因**:合成集字面量丰富、命中稀疏,预过滤命中率高,`× N_rules`&nbsp;因子被有效消除;真实 MITM 为对抗性规则集——含大量形如 (...key|auth|user...).\*? 的宽泛正则,字面量短而常见且含无界 .\*?,字面量命中后仍需整段验证,该成本占主导,故加速比收敛至约 32×。此为规则形态的固有属性,已通过 profile 与"全并/LimEx"等实验定位(见 minirehs/MINI\_VECTOR\_SCAN\_IMPL.md)。
* **存在性档快于定位档的原因**:打标仅需判定"哪些规则命中",可走纯位运算快路径、不追踪 leftmost-longest 偏移,分配亦更低。
* **两层分工的本质**:`minirehs`&nbsp;将"匹配次数"从&nbsp;`N_rules × N_packets`&nbsp;降至&nbsp;`~N_packets`;`go-pcre2-lite`&nbsp;进一步压低"每次匹配的常数"并约束 ReDoS。

二者叠加,构成 MITM 端到端由 0.19 提升至 6~7 MB/s 的来源。

**六、能力边界、生态影响与结论**

首先明确**适用边界**,以避免对数字的误读。该方案的强项在于字面量丰富、命中稀疏、规则数大的场景(指纹识别、扫描规则、IOC),加速比随规则数增长,合成集可达数十至上百倍;弱项在于充斥&nbsp;`.*`&nbsp;与常见短字面量的对抗性规则集,此时整段验证成本占主导,MVS 存在性约 32×、纯 Go 引擎约 2.5×。继续逼近 Hyperscan/vectorscan 量级需依靠&nbsp;**Teddy SIMD 默认化 + Rose-lite 链分解(命中点小邻域验证),****而非在逐条正则之上叠加"组合 gate 预筛"(后者经实测否决,在对抗集上反而更慢)。**

**此外存在两项工程约束:存在性档不提供精确偏移(需要位置时改用定位档,或以存在性档作快速门);**`go-pcre2-lite`&nbsp;兜底**强制****`CGO_ENABLED=1`**,而&nbsp;`minirehs本身在``CGO_ENABLED=0`&nbsp;下亦可纯 Go 运行,二者对 CGO 的要求不同,需在分发矩阵中分别处理。迁移时应按&nbsp;`MIGRATION.md核对少数文档化的语义差异(混合命名/无名组编号、重复组 capture 历史、RightToLeft;按名访问始终一致)。`

在**生态影响**层面,正则是 Yaklang 的底层原语,因此两项工作的收益不限于 MITM。其一,它提供了统一的正则底座:common/utils/regexp-utils&nbsp;已成为全生态的正则入口(RE2 优先、PCRE2 兜底),凡使用该入口的子系统——指纹识别&nbsp;`common/fp`、Suricata 规则&nbsp;`common/suricata`、流量守卫&nbsp;`common/crep/trafficguard`、SyntaxFlow 规则匹配——均自动继承"更快、布尔匹配零分配、ReDoS 有界、语法更全"的收益,此前因语法受限而无法使用的历史规则相当一部分可直接运行。其二,ReDoS 由潜在隐患转为平台属性:安全工具需处理用户提供或第三方来源的正则,旧引擎"永不超时"意味着单条异常正则即可拖垮引擎,PCRE2 的有界匹配将其转为可返回错误的可控事件。其三,`rehs`&nbsp;成为 yak 语言的一等能力:插件作者可通过&nbsp;`rehs.BuildGroup / Match / Find / MatchedPatterns实现一次编译、一次扫描海量规则,无需自行编写逐条循环。其四,``minirehs`&nbsp;零外部依赖、不加载任何动态库、CGO 不可用时优雅退化为纯 Go,契合 Yak 引擎跨平台可移植、分发稳定的定位。

**结论**:真实 MITM 87 条规则 + ~5MB 真实流量下,存在性打标约&nbsp;**32×**、纯 RE2 子集约&nbsp;**38×**、定位档约&nbsp;**14×**;单条正则更快(1.8×–9.6×)、布尔匹配零分配、ReDoS 默认有界、语法更全,代价是正则路径强制 CGO;复杂度由O(N\_rules × N\_bytes)&nbsp;降至&nbsp;`~O(N_bytes)`&nbsp;后,数百条正则的匹配确实更快,且加速比随规则数增长(合成集 50 条 11.6× → 1000 条 83.6×)。

综合而言,`go-pcre2-lite`&nbsp;降低了每次匹配的成本并扩展了可编译范围,`minirehs`&nbsp;将匹配次数由乘性关系转为加性关系;二者叠加,构成 Yakit MITM 内置规则由"逐条匹配 N 遍"到"一次扫描完成"的性能量变。

**七、如何使用**

可在MITM规则里配置是否使用更新后的正则规则。

![](https://mmbiz.qpic.cn/sz_mmbiz_jpg/jibGAup6p72EW22olMjGGbnSCvTpsu8fAsqysH1hjibLCpicfy7rwtDibAJiaIT38T0yg2pmBgrjicxIWwh42PhFLSK9mn3qcanFF9CV7Y8G5Q9ZI/640?wx_fmt=jpeg&from=appmsg#imgIndex=19)

***YAK***

**附录 A:复现信息**
# 合成规模:吞吐随 N 变化(图 1)CGO_ENABLED=1 go&nbsp;test&nbsp;./common/minirehs/ -run&nbsp;'^$'&nbsp;-bench BenchmarkSyntheticScale -benchmem -benchtime 3x# 真实 MITM 规则 + 真实流量(图 2)CGO_ENABLED=1 go&nbsp;test&nbsp;./common/minirehs/ -run&nbsp;'^$'&nbsp;\&nbsp; -bench&nbsp;'BenchmarkMVSExistence|BenchmarkMITMRealTraffic'&nbsp;-benchmem -benchtime 3x -timeout&nbsp;1800s# 单条正则层 PCRE2 vs dlclark(图 3 左)CGO_ENABLED=1 go&nbsp;test&nbsp;-bench . -benchmem -run&nbsp;'^$'&nbsp;github.com/VillanCh/go-pcre2-lite/...# 差分正确性(吞吐之外的护栏)go&nbsp;test&nbsp;./common/minirehs/ -run TestConsistency -short
![](https://mmbiz.qpic.cn/mmbiz_png/jibGAup6p72H0PJQJD2AOicIqXFdbmkDVdTlcicVZjfibMOZ4BukzGen4hmTohPK7vabet6ExU01AArdNRKibHdKDu6icCS8MhH68DKsayjRbJoS8/640?wx_fmt=png&from=appmsg#imgIndex=20)

***图一***

![](https://mmbiz.qpic.cn/mmbiz_png/jibGAup6p72EEAs8LMictrGHrZRTysXmoWQPMMR2ugYP0gSwU1lXtlT9bOo8SgvHuRiaCpxvjbbq3icADHgd8uo5Eb2OqdrT5YrWseR39Y8BH5Y/640?wx_fmt=png&from=appmsg#imgIndex=21)

***图二***

![](https://mmbiz.qpic.cn/mmbiz_png/jibGAup6p72HnDVSAHUia8XysOV6MTZmGS6SvVGxSY0Im57noibaZBzOPfm9pZ5oLWicicaydHttQ8uWIBC1dJ3CMM3kkYVbDMZ2NxDfvdKvibc5s/640?wx_fmt=png&from=appmsg#imgIndex=22)

***图三***

***YAK***

**附录 B:图表复现**

所有图表由&nbsp;`assets/make_figures.py`&nbsp;从&nbsp;`assets/data/*.csv`&nbsp;渲染,复用 precise-content-skills 的共享样式(`pc_style.py`,warm-paper 米色底、Okabe–Ito 色盲友好配色):
python3 -m venv venv && ./venv/bin/pip install matplotlib pandas numpy./venv/bin/python assets/make_figures.py &nbsp;&nbsp;# 输出 fig1..fig3 的 PNG + SVG

“`

| | | | | — | — | — | | 文件 | 内容 | 来源 | | assets/data/synthetic_scale.csv | 合成集吞吐/加速比 | 本机第一手 BenchmarkSyntheticScale | | assets/data/mitm_realtraffic.csv | 真实 MITM 吞吐/分配 | 本机第一手 BenchmarkMVSExistence / BenchmarkMITMRealTraffic | | assets/data/pcre2_single_regex.csv | PCRE2 vs dlclark | go-pcre2-lite 仓库自带基准(darwin/arm64) |

#

YAK

附录 C:关键源码位置

| | | | — | — | | 组件 | 路径 | | 多正则引擎 minirehs | common/minirehs/README.md 有完整设计与 PROFILE) | | yak rehs 库入口 | common/minirehs/rehs_api.go | | MITM 统一预过滤(不漏报) | common/yakgrpc/yakit/httpflow_replacer_prefilter.go | | MITM 染色/提取主流程 | common/yakgrpc/yakit/httpflow_replacer.go | | 正则统一入口(RE2 优先、PCRE2 兜底) | common/utils/regexp-utils/regexp-utils.go | | go-pcre2-lite | github.com/VillanCh/go-pcre2-lite v0.1.2(drop-in 包 .../regexp2) |


*说明:真实语料为本地 yaklang 项目库抽取的脱敏 HTTP 流量;rule4yak 规则集来源 SexyBeast233/rule4yak。

数据为特定硬件(darwin/arm64)与特定构建下的实测,绝对数字会随机器与规则集变化,但”加速比随 N 增长”与”两层正交叠加”的结论具有一般性。*

END

更新记录

Yakit  v1.4.8-0710

  1. WebFuzzer新增API接口测试功能

  2. 全局配置增加“关闭二次弹窗”配置开关

  3. 优化部分右键菜单快捷执行

  4. 修复全局配置AI模型缓存问题

  5. 修复history批量染色处理卡顿崩溃问题

  6. 修复history点击右键菜单变白的问题

  7. 优化引擎连接流程,增加可选工作空间

  8. 优化右键执行插件的交互和展示

  9. 登录后可使用移动端控制功能,绑定飞书/钉钉远程控制AI Agent功能

  10. YakRunner优化AI代码编写的展示和交互

  11. 优化WebFuzzer的按钮展示

Memfit  v1.0.3-0710

  1. 修改工具调用卡片(icon、工具名称展示,理由位置、生成参数卡片样式)

  2. 修改任务执行详情(修改标题、不新开tab)

  3. 自由对话新增子agent任务描点定位

  4. 优化自由对话待办清单展示,可展示已完成/进行中/未完成

  5. 子Agent任务增加跳过和查看任务详情

  6. 优化发送问题后前端UI展示逻辑

  7. 优化自由对话任务详情展示逻辑,只展示一个,不重复多开

Yaklang 1.4.8-beta2

  1. 新增飞书/钉钉远程控制AI Agent功能(需要登录后使用)

  2. 新增代码审计子 Agent 与 react_loop 增强

  3. 新增大量 MCP 工具集(chaos maker / fingerprint / http builder 等)

  4. 修复大型项目 SyntaxFlow 扫描内存与卡死问题,重构 SSA 编译单元流式编译

  5. 修复 HTTPFlow 标签更新、插件取消上下文和 facade TLS 加固

  6. 修复 cybertunnel 隧道客户端错误处理与 MITM 热补丁并发问题

  7. 新增 Windows ARM64 CI 支持与 slim(轻量版) 门禁测试

YAK官方资源

Yak 语言官方教程:

https://yaklang.com/docs/intro/

Yakit 视频教程:

https://space.bilibili.com/437503777

Github下载地址:

https://github.com/yaklang/yakit

Yakit官网下载地址:

https://yaklang.com/

Yakit安装文档:

https://yaklang.com/products/download_and_install

Yakit使用文档:

https://yaklang.com/products/intro/

常见问题速查:

https://yaklang.com/products/FAQ


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Yak Project YAK YAK《百倍正则加速:让 Yak 中的正则支持统一编译与完整 PCRE2》

评论:0   参与:  0