基于 RC4 状态机 + 多项式模型的名字评分枚举工具。通过 XP(虚评)和 XD(虚单)筛选高分名字。
# 克隆仓库
git clone https://github.com/GoldenFish123321/Namerena-pbb_new.git
cd Namerena-pbb_new
# 复制示例配置, 修改参数
cp config.example.yaml config.yaml
# 一键启动 (自动检测环境、安装依赖、编译引擎)
./run.sh -c config.yaml # Linux / Termux / Docker
./run.sh -y -c config.yaml # 跳过确认 (CI/Docker)
run.bat -c config.yaml # Windows (自动检测 icpx/g++/cl, Zen5 自动启用 MSYS2 GCC)
run.bat -y -c config.yaml # Windows 跳过确认(也可以不写-c参数,默认使用config.json/yaml/toml)
首次运行自动:检测系统包管理器 → 编译 C++ 引擎 → 启动。所有系统级安装前会确认(-y 跳过)。
支持 JSON / YAML / TOML 三种格式,扩展名自动识别。不指定 -c 时依次尝试 config.json → config.yaml → config.toml。
debug_mode: 0 # 0=关闭 1=开启 (--debug 启用)
team_name: "test"
prefixes:
- name: "test-" # '+' = 无前缀
- name: "pbb-"
- name: "abc-" # 多前缀: mode 1 每个都跑全程
suffixes: # mode 2/4 每个 chunk 随机选一个
- name: "+"
character_set:
single_char_length: 4 # 1/2/3/4 字节
types: [2] # 字符集类型 (见下方对照表)
custom_values: "🐒🐵🐊🦎🐍🐛🙈🙉🙊🐉" # 字符串 (也兼容旧格式数字列表)
enumeration:
mode: 2 # 1=顺序 2=随机(区间) 3=随机(逐位)⚠️ 4=随机(配对)
variable_length: 8 # 可变字符数
ranges:
- start: 0 # 起始编号
end: 100000000 # 结束编号 (不含), -1=几乎无限
collection:
xp_min: 4900 # 虚评最低阈值
xd_min: 5600 # 虚单最低阈值
collect_mode: 1 # 0=不收集 1=硬编码阈值 2=自定义阈值
special_thresholds: # collect_mode=2 时生效
eight_v_min: 777
seven_v_min: 700
hl_min: 93
hp398_eight_v_min: 741
output:
output_xp: 1 # 输出文件是否包含分数
log_output: 1 # 任务日志: 0=文件 1=屏幕
speed_output: 1 # 速度信息: 0=文件 1=屏幕
result_file: "-" # - =时间戳 + =随机名 其他=自定义
threads:
worker_threads: -1 # -1 =自动检测CPU核心数示例配置文件见 config.example.json / config.example.yaml / config.example.toml。
| mode | 行为 | 受控参数 |
|---|---|---|
| 1 顺序 | [start, end) 区间内按编号逐个枚举 |
ranges[0].start / end |
| 2 随机(区间) | 每个 chunk 随机起点 + 剩余位顺序展开,chunk 内无重复 | ranges 控 chunk 数,范围 = charset_len^vlen |
| 3 随机(逐位) |
每位独立随机选择,chunk 内大量重复(不推荐) | 同上 |
| 4 随机(区间+配对) | 类似 mode 2,prefix/suffix 配对,chunk 内无重复 | 同上 |
随机模式关键概念:
- 次数 =
ceil((end - start) / 1M)个 chunk,每个 chunk 1M 个名字(向上取整:mode 2/4 的 consumer 中R=L+CHUNK_SIZE覆盖 producer 区间,即使最后一块不足 1M 也处理 1M) - 随机范围 =
charset 字符数 ^ variable_length(自动计算) - 例:10 个 emoji +
variable_length: 4→ 范围 = 10⁴ = 10000 ranges[0].end设大一些获得更多采样(如 100M = 100 chunks = 1 亿次随机)ranges[0].end: -1→ 几乎无限(uint64_t最大值 ≈ 1.8×10^19)
mode 2/3/4 配合
seed可实现确定性随机——同 seed + 同 range → 任意线程数下结果完全一致。
mode 3 每个名字的每个可变位独立随机抽取(rng() % clen),而 mode 2/4 用计数器进位编码(i → clen 进制展开)保证 chunk 内所有名字唯一。
由于引擎为 chunk 分配的可变位数 varlen_task 刚好满足 clen^varlen_task ≥ 1M(chunk 大小),搜索空间紧贴抽取量。根据生日悖论:
| 字符集 | clen | varlen_task | random_range_max | 期望唯一名 / 1M | 重复率 |
|---|---|---|---|---|---|
| 10 字符 (emoji) | 10 | 6 | 1,000,000 | ~63.2 万 | ~37% |
| 64 字符 | 64 | 4 | 16,777,216 | ~97.1 万 | ~3% |
| vlen 不足时 | — | — | clen^vlen ≪ 1M |
— | 灾难 |
建议用 mode 2 替代 mode 3——同样随机前缀/后缀和随机起点,但编码逻辑保证 0% chunk 内重复,实际搜到的有效名字更多。
mode 1 (顺序): 每个 prefix 遍历完整 range → 总名数 = prefix 数 × range。suffix 按 prefix index 轮转配对。
mode 2/3 (随机): 总 chunk 数 = range / 1M,每个 chunk 随机选一个 prefix 和 suffix。多 prefix 只扩大随机池,不翻倍总次数。
mode 4 (随机+配对): suffix 与 prefix 配对(同 index),其余同 mode 2/3。
例:3 个 prefix + 2 个 suffix + range=100M:
- mode 1: 3 × 100 = 300 chunks,每个 prefix 跑 100 chunks
- mode 2/3: 100 chunks,每个随机从 3×2=6 种 (prefix,suffix) 组合中选
| scl | type | 内容 |
|---|---|---|
| 1 | 1-5 | 数字 / 小写字母 / 大写字母 / 自定义 / ASCII |
| 2 | 1-8 | 希腊 / 俄文 / 拉丁 / 自定义 / Unicode |
| 3 | 1-8 | 全部汉字 / 常用汉字 / 平假名 / 片假名 / 盲文 / 扩展汉字 / 自定义 / Unicode |
| 4 | 1-3 | 扩展汉字 / 自定义 / Unicode |
自定义字符集 直接写原始字符,自动 UTF-8 编码:
# scl=3 用中文
custom_values: "你好世界测试名字"
# scl=4 用 emoji
custom_values: "🐒🐵🐊🦎🐍🐛🙈🙉🙊🐉"python3 main.py -c config.yaml \
--team "测试队" \
--threads 8 \
--mode 1 --vlen 4 \
--range-start 0 --range-end 50000 \
--xp-min 5000 --xd-min 6000 \
--collect-mode 2 \
--output-xp 1 \
-o myrun.txt \ # 输出文件名 (可选: + 随机, - 时间戳)
--output-dest both \ # 输出目标 (可选: file/stdout/both)
--scl 3 --types 7 --custom-values "你好世界"| 参数 | 覆盖字段 | 示例 |
|---|---|---|
--rebuild |
(无) 强制重编 C++ 引擎 | --rebuild |
--team |
team_name |
--team "测试" |
--threads |
threads.worker_threads |
--threads 8 |
--mode |
enumeration.mode |
--mode 1 |
--vlen |
enumeration.variable_length |
--vlen 4 |
--range-start |
enumeration.ranges[0].start |
--range-start 0 |
--range-end |
enumeration.ranges[0].end |
--range-end 50000 |
--xp-min |
collection.xp_min |
--xp-min 5000 |
--xd-min |
collection.xd_min |
--xd-min 6000 |
--collect-mode |
collection.collect_mode |
--collect-mode 2 |
--output-xp |
output.output_xp |
--output-xp 1 |
-o / --output-file |
output.result_file |
-o myrun.txt / -o + |
--output-dest |
(无) 控制输出位置 | --output-dest stdout / --output-dest both |
--debug |
debug_mode |
引擎诊断输出 |
--seed N |
seed |
随机种子 (mode 2/3/4 确定性随机) |
--scl |
character_set.single_char_length |
--scl 3 |
--types |
character_set.types |
--types 1,7 |
--custom-values |
character_set.custom_values |
--custom-values "你好" |
启动时自动检测环境并输出摘要:
[env] OS: linux x86_64
[env] CPU: x86_64 (6 cores)
[env] Python: 3.12.3
[env] compilers: icpx(AVX-512) -> g++(AVX2)
编译器按性能优先级自动选择,编译失败自动回退:
| 平台 | engine 编译器优先级 | pbb_core 编译器优先级 | 指令集 |
|---|---|---|---|
| Linux x86_64 | icpx → g++ | icpx → g++ | AVX-512 > AVX2 |
| Linux ARM / Termux | g++ | g++ | NEON (128bit) |
| Windows x86_64 | icpx → g++ → MSVC | icpx → g++ → MSVC | AVX2 (icpx 固定) |
| Windows AMD Zen5 | MSYS2 GCC (→ icpx → MSVC) | 同 engine | AVX2 + -march=znver5 |
Windows icpx 固定
-xCORE-AVX2。-xHost在 Arrow Lake 上仍导致 LLVM 编译期 crash(2026-06-01 确认)。g++ 编译 pbb_core 自动加-static静态链接,编译成功即用。AMD Zen5 用户:
run.bat自动检测C:\msys64\ucrt64\bin\g++.exe,检测到后提升 MSYS2 GCC 为最优编译器,build.py自动加-march=znver5。
编译输出(正常模式简洁,--debug 显示完整命令):
[build] pbb_core: icpx (AVX2)
[build] engine: icpx (AVX2)
运行时会打印 SIMD 级别:
[engine] SIMD: AVX2
引擎运行时实时输出进度 (每 100 个 task):
task99 finished,task_mex=100,count:0.000100T
tot=17, (741,5615,5933),time: 28.54s, speed: 0.3027T/d,time left:0h0m0s
task_mex— 最小未完成 task_id (全部完成时 = 总 task 数)(八围, XP, XD)— 当前最大八围总分、虚评、虚单time left— 预估剩余时间
配置 output.result_file 控制输出文件名:
| 值 | 含义 | 示例 |
|---|---|---|
- |
时间戳 (默认) | result_20260601_153045.txt |
+ |
随机 hex | result_a3f2b1c8.txt |
| 其他 | 自定义名称 | my_output.txt |
文件名自动加上 out/ 前缀,无需手动写。CLI 可覆盖:--output-file myrun.txt / -o +
--output-dest 控制结果输出位置:
| 值 | 行为 |
|---|---|
file |
仅写入 out/<文件名> (默认) |
stdout |
仅打印到终端 (不保留文件) |
both |
写入文件 + 终端打印 |
结果格式:
名字@队伍名 XP XD
test-🙈🐛🐊🐍@test 5021 5003
collect_mode=1/2 时特殊属性号写入 out/blue.txt。output_xp=0 时不显示分数。
build.py (Python) pbb_engine (C++ 子进程)
───────────────── ───────────────────────────
编译器自动检测 (icpx/g++/cl) producer-consumer 多线程引擎
指令集自动探测 (AVX512/AVX2/ RC4 KSA → 属性评分 → 技能分布
NEON) hanxu_Poly 多项式特征扩展
统一编译 + 回退机制 MODEL 线性模型打分 (XP/XD)
stderr 实时进度 → Python 解析
engine.py (Python) src/ 核心 (header-only)
───────────────── ───────────────────────────
字符集构建 (pbb_core) common.hpp 类型 + SIMD 检测
stdin 管道传参 utils.hpp AVX512/AVX2/NEON
Popen → stderr 逐行读取 name.hpp RC4 状态机
结果统计 scoring_1035.hpp 评分流水线
main.py (Python) engine.hpp 引擎主循环
─────────────────
CLI + 配置解析 + 调用 engine.run()
项目本质是对整数区间 [L, R) 的纯函数遍历(f(i) → score,各 i 间零依赖),
因此并行切分天然分两层:
| 层 | 单位 | 切分者 | 大小 |
|---|---|---|---|
| chunk | 引擎内部线程级 | engine.hpp producer |
CHUNK_SIZE = 1M 名字 |
| task | 分布式级 | 服务端 (规划中) | 服务端按更大粒度切总 range |
engine.run() 已收敛为单机 / 服务端 / 客户端三方共用的统一入口:
run(config, engine_bin=None, out_dir=None, result_file="result.txt")
# config 模式 A: 含 character_set → 内部构建字符集 (单机)
# config 模式 B: 含 charset_hex → 直接使用 (服务端下发, 免重复构建)
# config["seed"]: 随机种子 (mode 2/3/4)
# None → 时间熵 (单机默认, 每次结果不同)
# 具体数值 → 确定性 (分布式: 同 seed → 结果可复现/可去重, 与线程数无关)
# result_file: 多 task 并发同目录时传唯一名, 避免撞文件
# 返回: {results, max_xp, max_xd, max_sum, found, speed}
# max_*/found/speed 由引擎权威输出 (SUMMARY 行), Python 不重算。
# speed 为纯算力吞吐 (名字/秒, 不含子进程 fork / 字符集初始化 / 文件读取)。随机性与线程数解耦:每个 chunk 的随机性派生自
(seed, task_id), 与"用几个线程、谁来跑、跑的顺序"完全无关。同 seed + 同 range 在任意线程数下结果完全一致 (已用 3/6/12 线程 md5 对拍验证)。这是分布式 task 超时回收重发的前提: 服务端为每个 task 存固定 seed,重发时下发同一 seed,无论分给几核机器都产生相同名字集,可去重。
项目支持两种评分模型,通过修改 src/engine.hpp 一行 #include 切换:
| 文件 | 模型 | 特征维度 | 说明 |
|---|---|---|---|
src/scoring_1035.hpp |
XP/XD (默认) | 44→1034 | 虚评/虚单,来自 pbb_all.cpp |
src/scoring_1124.hpp |
SQP/SQD | 46→1124 | 对强评/强单更好的拟合,移植自 Namerena-HtmlTools |
切换方式:修改 src/engine.hpp 第 13 行
#include "scoring_1035.hpp" // XP/XD (默认)
// #include "scoring_1124.hpp" // SQP/SQD重新编译并运行:
./run.sh --rebuild
./run.bat --rebuildSQP/SQD 与 XP/XD 的特征工程差异:
- 技能频次使用衰减叠加(zd/kill 系数),而非原始频次
- 护盾非线性变换、Shadow 加权公式、隐匿标志位等不同
- 多项式展开 1124 维(含 4 对排除项),vs 1034 维
- 均含 V 值过滤器(性能优化)
100M 基准对比(6核 g++ AVX2):
| XP/XD | SQP/SQD | |
|---|---|---|
| Speed | 2.54M/s | 2.34M/s |
| Found | 17 | 36 |
| Max | XP=5615 XD=5933 | SQP=5586 SQD=5878 |
├── run.sh / run.bat # 入口 (建 .venv + 装依赖, -y 跳过确认)
├── build.py # 编译器检测 + SIMD 探测 + 统一编译
├── engine.py # 引擎执行: 构建字符集 → Popen → 解析结果
├── main.py # 编排层: CLI 解析 + 配置加载
├── config_schema.py # config→engine 键名映射唯一真相源 (FieldDef + CONFIG_MAP)
├── engine_main.cpp # C++ 引擎入口
├── build/ # 编译产物 (pbb_engine, pbb_core.{so,pyd})
├── out/ # 运行输出 (result_*.txt, blue.txt)
├── config.example.json # JSON 配置示例
├── config.example.yaml # YAML 配置示例
├── config.example.toml # TOML 配置示例
└── src/
├── common.hpp # 类型 + SIMD 自动检测 (AVX512/AVX2/NEON)
├── charset_data.hpp # 字符集原始数据 (希腊/俄文/拉丁/盲文/汉字)
├── utils.hpp # median/sort10 + 三路 SIMD (AVX512/AVX2/NEON)
├── charset.hpp # 字符集加载 + Unicode 编码
├── name.hpp # RC4 状态机 (KSA → PRGA → 技能分布)
├── scoring.hpp # 评分流水线 (旧文件, 已被 scoring_1035.hpp 替代)
├── scoring_1035.hpp # XP/XD 评分模型 (44→1034, 默认)
├── scoring_1124.hpp # SQP/SQD 评分模型 (46→1124)
├── engine.hpp # 引擎主循环 (改 include 切换模型)
└── bridge.cpp # pybind11 字符集数据绑定