chore: 初始骨架 — 设计文档 + 计划
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,215 @@
|
||||
# QR 码生成器 — 设计文档
|
||||
|
||||
**日期**: 2026-06-16
|
||||
**作者**: 刘航宇
|
||||
**语言**: Rust
|
||||
**项目路径**: `D:\Code\doing_exercises\programs\QRGen\`
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
从零实现 ISO/IEC 18004 QR 码生成器,不依赖任何第三方 QR 编码库。算法全手写,
|
||||
输出 PNG / SVG / 终端 ASCII。后续扩展 Tauri GUI。
|
||||
|
||||
## 2. 支持范围
|
||||
|
||||
| 维度 | 范围 |
|
||||
|------|------|
|
||||
| **QR 版本** | 1~40(21×21 ~ 177×177 模块) |
|
||||
| **纠错级别** | L (7%), M (15%), Q (25%), H (30%) |
|
||||
| **编码模式** | 数字 / 字母数字 / 字节 / 汉字 (Shift JIS) |
|
||||
| **输出格式** | PNG(`image` crate)、SVG、终端 ASCII |
|
||||
| **自动版本选择** | 根据数据长度 + 纠错级别自动选最小版本 |
|
||||
|
||||
## 3. 项目结构
|
||||
|
||||
```
|
||||
QRGen/
|
||||
├── Cargo.toml # workspace: core + cli
|
||||
├── core/ # 纯算法库,尽量零依赖
|
||||
│ ├── Cargo.toml
|
||||
│ └── src/
|
||||
│ ├── lib.rs
|
||||
│ ├── qr.rs # 顶层 API
|
||||
│ ├── version.rs # 版本参数表 (40 行硬编码)
|
||||
│ ├── encoder/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── mode.rs # 编码模式定义
|
||||
│ │ ├── segment.rs # 数据分段与模式选择
|
||||
│ │ └── bitstream.rs # 比特流拼接
|
||||
│ ├── ecc/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── galois.rs # GF(2⁸) 运算 + 预计算表
|
||||
│ │ └── reed_solomon.rs # RS 纠错码生成
|
||||
│ ├── matrix/
|
||||
│ │ ├── mod.rs
|
||||
│ │ ├── grid.rs # 模块网格数据结构
|
||||
│ │ ├── patterns.rs # 定位/对齐/时序图案
|
||||
│ │ ├── placement.rs # 数据字节蛇形排列
|
||||
│ │ └── mask.rs # 8 种掩码 + 评分
|
||||
│ └── render/
|
||||
│ ├── mod.rs
|
||||
│ ├── png.rs # PNG 渲染 (image crate)
|
||||
│ ├── svg.rs # SVG 渲染
|
||||
│ └── ascii.rs # 终端 ASCII 渲染
|
||||
├── cli/ # CLI 工具
|
||||
│ ├── Cargo.toml
|
||||
│ └── src/
|
||||
│ └── main.rs
|
||||
└── docs/
|
||||
└── superpowers/specs/
|
||||
```
|
||||
|
||||
## 4. 数据流水线
|
||||
|
||||
```
|
||||
输入字符串
|
||||
→ 数据分析 (mode.rs + segment.rs) → Vec<Segment>
|
||||
→ 版本选择 (version.rs) → Version (1~40)
|
||||
→ 比特流编码 (bitstream.rs) → Vec<u8> (data codewords)
|
||||
→ RS 纠错编码 (reed_solomon.rs) → Vec<u8> (final sequence)
|
||||
→ 模块布局 (matrix/) → Matrix (bitmap)
|
||||
→ 掩码评分 (mask.rs) → Matrix (best mask)
|
||||
→ 渲染输出 (render/) → PNG / SVG / ASCII
|
||||
```
|
||||
|
||||
### 4.1 数据分析
|
||||
|
||||
1. 扫描输入字符串,分析字符集
|
||||
2. 根据字符分布选择最优编码模式(混合内容自动分段)
|
||||
3. 每段包含:模式指示符 + 字符计数 + 编码数据
|
||||
|
||||
### 4.2 版本选择
|
||||
|
||||
硬编码 ISO 18004 附录中的容量表(40 版本 × 4 纠错级别),
|
||||
根据总比特数查表选最小合适版本。用户可手动覆盖。
|
||||
|
||||
### 4.3 比特流编码
|
||||
|
||||
- 各段按模式规则编码为比特
|
||||
- 添加终止符(最多 4 bit)
|
||||
- 补零到 8-bit 边界
|
||||
- 填充码字 0xEC/0x11 交替至满容量
|
||||
|
||||
### 4.4 RS 纠错编码
|
||||
|
||||
- GF(2⁸) 基于 `x⁸ + x⁴ + x³ + x² + 1` (0x11D)
|
||||
- 预计算 exp/log 表加速乘除法
|
||||
- 生成多项式动态构造
|
||||
- 多项式长除法求余数(纠错码字)
|
||||
|
||||
### 4.5 模块布局
|
||||
|
||||
1. 绘制空白矩阵
|
||||
2. 放置定位图案(3 个角)
|
||||
3. 放置对齐图案(版本相关数量)
|
||||
4. 放置时序图案 + 暗模块
|
||||
5. 保留格式信息区域(15 bit)
|
||||
6. 保留版本信息区域(版本 ≥ 7,18 bit)
|
||||
7. 按蛇形路径填入数据比特
|
||||
8. 尝试 8 种掩码,对每种:
|
||||
- 计算格式信息
|
||||
- 若版本 ≥ 7 计算版本信息
|
||||
- 评分
|
||||
9. 选最低惩罚分掩码,写入最终格式/版本信息
|
||||
|
||||
### 4.6 掩码评分规则
|
||||
|
||||
| 规则 | 条件 | 惩罚 |
|
||||
|------|------|------|
|
||||
| 规则 1 | 连续 5+ 同色行/列 | N1 + k-5 |
|
||||
| 规则 2 | 同色 2×2 方块 | 每块 +3 |
|
||||
| 规则 3 | `1011101` 模式 | 每次 +40 |
|
||||
| 规则 4 | 暗模块占比偏离 50% | 每 5% +10 |
|
||||
|
||||
### 4.7 渲染输出
|
||||
|
||||
- **PNG**: 依赖 `image` crate,逐模块像素填充,可调模块大小 + 白边
|
||||
- **SVG**: 纯字符串拼接,无依赖,`<rect>` 逐模块
|
||||
- **ASCII**: 终端输出,`██` / ` ` 双字符渲染,利用 Unicode 半方块实现近似正方形
|
||||
|
||||
## 5. CLI 接口
|
||||
|
||||
```
|
||||
qrgen "content" [options]
|
||||
|
||||
Options:
|
||||
-o, --output <FILE> 输出文件(.png/.svg),不指定则终端 ASCII
|
||||
-l, --level <LEVEL> 纠错级别 L/M/Q/H [default: M]
|
||||
-v, --version <VER> 手动指定版本 (1-40),不指定则自动
|
||||
-s, --size <PX> 模块像素大小(PNG) [default: 4]
|
||||
-m, --margin <N> 白边模块数 [default: 4]
|
||||
--mode <MODE> 强制编码模式 [auto]
|
||||
--invert 反色
|
||||
-h, --help 帮助
|
||||
```
|
||||
|
||||
示例:
|
||||
```bash
|
||||
qrgen "https://example.com" # 终端 ASCII
|
||||
qrgen "hello" -o qr.png -s 10 # 大模块 PNG
|
||||
qrgen "data" -o qr.svg -l H # SVG, 高纠错
|
||||
qrgen "12345" --mode numeric -v 5 # 纯数字, 版本5
|
||||
```
|
||||
|
||||
## 6. 核心 API(core/lib.rs)
|
||||
|
||||
```rust
|
||||
pub struct QrConfig {
|
||||
pub level: EcLevel, // 默认 M
|
||||
pub version: VersionMode, // 默认 Auto
|
||||
pub mode: ModeHint, // 默认 Auto(混合自动分段)
|
||||
pub margin: u8, // 默认 4
|
||||
}
|
||||
|
||||
pub enum VersionMode {
|
||||
Auto,
|
||||
Fixed(u8),
|
||||
}
|
||||
|
||||
pub struct QrCode {
|
||||
// 内部持有最终的 Matrix + 版本/级别元数据
|
||||
}
|
||||
|
||||
impl QrCode {
|
||||
/// 编码字符串,失败返回 Err
|
||||
pub fn encode(text: &str, config: QrConfig) -> Result<Self>;
|
||||
|
||||
/// 导出为 PNG bytes
|
||||
pub fn to_png(&self, module_size: u8) -> Vec<u8>;
|
||||
|
||||
/// 导出为 SVG 字符串
|
||||
pub fn to_svg(&self) -> String;
|
||||
|
||||
/// 导出为 ASCII 字符串
|
||||
pub fn to_ascii(&self, invert: bool) -> String;
|
||||
|
||||
/// 获取原始模块矩阵(供外部渲染使用)
|
||||
pub fn modules(&self) -> &[Vec<bool>];
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 测试策略
|
||||
|
||||
| 层级 | 内容 | 覆盖率目标 |
|
||||
|------|------|-----------|
|
||||
| **单元测试** | GF(2⁸) 运算、RS 编码、模式编码、掩码评分 | ≥ 80% |
|
||||
| **集成测试** | 已知字符串 → 生成的 PNG 被 zxing 解码验证 | 关键路径 |
|
||||
| **回归测试** | 固定输入 → 固定矩阵黄金数据(标准附录参考值) | 关键算法 |
|
||||
| **属性测试** | 随机字符串 → 编码解码往返 | 可选 |
|
||||
|
||||
## 8. 不实现的范围(明确排除)
|
||||
|
||||
- Micro QR Code
|
||||
- QR Code 解码(本项目只管生成)
|
||||
- 结构化附加(Structured Append)
|
||||
- FNC1 模式
|
||||
- ECI 编码指示符
|
||||
- 艺术 QR 码(带 logo 嵌入等)
|
||||
|
||||
## 9. 里程碑
|
||||
|
||||
1. **M1**: GF(2⁸) + Reed-Solomon — 最核心算法
|
||||
2. **M2**: 编码 + 比特流 — 能产出有效码字序列
|
||||
3. **M3**: 矩阵布局 + 掩码 — 能产出完整 QR 矩阵
|
||||
4. **M4**: 渲染输出 — PNG + SVG + ASCII
|
||||
5. **M5**: CLI — 完整的命令行工具
|
||||
Reference in New Issue
Block a user