Files
QRGen/docs/superpowers/specs/2026-06-16-qrcode-generator-design.md

7.0 KiB
Raw Permalink Blame History

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~4021×21 ~ 177×177 模块)
纠错级别 L (7%), M (15%), Q (25%), H (30%)
编码模式 数字 / 字母数字 / 字节 / 汉字 (Shift JIS)
输出格式 PNGimage 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            帮助

示例:

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. 核心 APIcore/lib.rs

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 — 完整的命令行工具