🀫 QRGen

从零手搓的 QR 码生成/解码器 — ISO/IEC 18004 完整实现

version rust tauri react axum docker license tests clippy prettier eslint vitest

--- ## 简介 QRGen 是 **从零手写** 的 QR 码(二维码)生成/解码器,完整实现 ISO/IEC 18004 国际标准。不依赖任何第三方 QR 编码/解码库,所有算法(Galois 域运算、Reed-Solomon 纠错编解码、BCH 格式编解码、掩码评分、定位检测)均从底层手搓。 支持 **四种使用方式**:程序库(`qr-core`)、命令行(`qrgen`)、桌面 GUI(`qrgen-gui`)、Web 服务(`qrgen-web`)。支持**编码**(文本→QR)和**解码**(QR→文本)双向闭环。 ## 架构 ```mermaid graph TB subgraph Frontend["React 前端 (GUI)"] App[App.tsx 三栏布局] Modes[7 种模式表单] Preview[实时预览区] Export[导出面板] History[历史记录] App --> Modes App --> Preview App --> Export App --> History end subgraph Web["Web 服务 (axum)"] HTML[内嵌 HTML 页面] API[GET /api/qr + POST /api/decode] end subgraph CLI["CLI 命令行"] Clap[clap 编码 + --decode 解码] end subgraph IPC["Tauri IPC 桥接"] Commands[6 个 Tauri commands] end subgraph Core["Rust core 库 (qr-core)"] Encoder[编码层] Decoder[解码层] ECC[纠错层] Matrix[矩阵层] Render[渲染层] Encoder --> ECC Decoder --> ECC ECC --> Matrix Matrix --> Render end Modes --> Commands Commands --> Encoder Clap --> Encoder HTML --> API API --> Encoder ``` ### 数据流水线 ```mermaid sequenceDiagram actor U as 用户 participant UI as React UI / CLI / Web participant Q as QrCode::encode() participant E as 编码器 participant RS as Reed-Solomon participant M as 矩阵布局 participant R as 渲染器 U->>UI: 输入文本 UI->>Q: encode(text, config) Q->>E: 分析字符集, 自动分段 E->>E: 模式编码 E->>RS: 数据码字 RS->>RS: 纠错码字生成 + 交错 RS->>M: 最终码字序列 M->>M: 功能图案 + 蛇形排列 + 掩码 M->>R: QR 矩阵 R->>UI: PNG / SVG / ASCII Note over U,R: --- 解码流水线 (逆向) --- U->>UI: 上传图片 UI->>Q: decode_image(bytes) Q->>R: 图像二值化 + 定位图案检测 R->>M: 布尔矩阵 M->>M: 读取格式/版本信息 + 解掩码 + 蛇形提取 M->>RS: 数据码字 + 纠错码字 RS->>RS: 去交错 + 伴随式 + Berlekamp-Massey + Chien + Forney RS->>E: 纠错后数据码字 E->>E: 模式解码(数字/字母/字节/汉字) E->>UI: 解码文本 ``` ## 功能 ### 核心算法(全部手写) | 模块 | 内容 | 说明 | |------|------|------| | Galois 域 | GF(2⁸) 四则运算 + 幂运算 | 预计算 exp/log 表,本原多项式 0x11D | | Reed-Solomon | RS 纠错码生成 + 数据交错 | 生成多项式动态构造,多项式长除法 | | 编码模式 | 数字 / 字母数字 / 字节 / 汉字 | 4 种模式,自动分段选最优 | | 矩阵布局 | 定位/对齐/时序图案 + 蛇形排列 | 8 种掩码 + 四规则惩罚评分 | | BCH 编码 | 格式信息 BCH(15,5) + 版本信息 BCH(18,6) | 两级纠错保护 | | 版本容量 | 40 版本 × 4 纠错级别完整参数表 | 自动版本选择 | ### CLI 命令行 ```bash # 终端 ASCII 预览 qrgen "Hello World" # 生成 PNG qrgen "https://example.com" -o qr.png -s 8 # 生成 SVG(高纠错) qrgen "重要数据" -o qr.svg -l H # 解码 QR 码图片 qrgen --decode qr.png ``` ### GUI 桌面应用 - **7 种编码模式**:文本 / URL / WiFi / vCard(10字段) / Email / 电话 / SMS - **解码**:选择图片文件,解码 QR 码为文本 - **实时预览**:200ms 防抖,PNG 即时渲染 - **多格式导出**:PNG(可调模块大小)/ SVG / 复制到剪贴板 - **历史记录**:最近 50 条,点击回填,支持删除和清空 - **暗色模式**:跟随系统,磨砂玻璃效果 - **纠错级别可调**:L (7%) / M (15%) / Q (25%) / H (30%) ### Web 服务 - **内嵌 HTML 界面**:复刻 GUI 三栏布局,7 种编码模式 - **REST API**:`GET /api/qr` → PNG / SVG;`POST /api/decode` → 上传图片返回文本 - **Docker 部署**:17.7MB Alpine 镜像,开箱即用 ## 安装 ### 从源码构建 ```bash git clone git@lhy-git.liuhangyv.top:Serendipity/QRGen.git cd QRGen # 安装前端依赖 cd gui/src-frontend && pnpm install && cd ../.. # CLI cargo build --release -p qrgen # Web 服务 cargo build --release -p qrgen-web # GUI + NSIS 安装包 cd gui/src-frontend && pnpm build && cd ../.. cd gui && src-frontend/node_modules/.bin/tauri.cmd build ``` > **要求**:Windows 10+(GUI 需 WebView2),Rust 1.95+,Node.js 22+ ### Docker(Web 服务) ```bash # 拉取镜像(或本地构建) docker build -t qrgen-web -f web/Dockerfile . # 运行 docker run -d --name qrgen-web --restart unless-stopped -p 3000:3000 qrgen-web # docker-compose # 见 G:\qrgen-web\docker-compose.yaml(NAS 部署用) ``` ## 开发 ```bash # 开发模式 GUI(热更新) cd gui/src-frontend && pnpm dev # 终端1: 前端 cargo run -p qrgen-gui # 终端2: Rust 后端 # CLI 开发 cargo run -p qrgen -- "Hello World" # Web 开发 cargo run -p qrgen-web # → http://localhost:3000 # Rust 测试 cargo test --lib # 81 unit # 前端测试 cd gui/src-frontend && pnpm test # vitest # 前端类型检查 cd gui/src-frontend && pnpm tsc --noEmit # Rust lint cargo clippy -- -D warnings # 前端代码检查 cd gui/src-frontend && pnpm lint # eslint cd gui/src-frontend && pnpm format:check # prettier # Git hooks(提交前自动运行) # pre-commit: lint-staged(prettier + eslint) # commit-msg: commitlint(Conventional Commits) ``` ### 技术栈 | 层 | 技术 | |---|---| | 桌面框架 | Tauri 2.x | | GUI 前端 | React 18 + TypeScript (strict) | | UI 样式 | TailwindCSS 3 | | 状态管理 | React Context + useReducer | | Web 服务 | axum 0.8 + tokio | | 核心库 | Rust (qr-core) | | CLI | clap + anyhow | | 前端包管理 | pnpm | | 桌面打包 | NSIS | | 容器化 | Docker (alpine, 17.7MB) | ### 项目结构 ``` QRGen/ ├── core/ # Rust 核心库(算法全部在此) │ └── src/ │ ├── qr.rs # 顶层 API — QrCode::encode() │ ├── version.rs # 40 版本容量表 + 自动选择 │ ├── ecc/ │ │ ├── galois.rs # GF(2⁸) 运算 + exp/log 表 │ │ └── reed_solomon.rs # RS 纠错码 + 数据交错 │ ├── decoder/ # QR 解码器(从零手写) │ │ ├── mod.rs # 顶层 API:decode_image + decode_matrix │ │ ├── bch.rs # BCH(15,5)+BCH(18,6) 查表解码 │ │ ├── format.rs # 格式信息 + 版本信息读取 │ │ ├── extract.rs # 逆向蛇形排列提取码字 │ │ ├── deinterleave.rs # 逆向 RS 数据交错 │ │ ├── rs_decode.rs # RS 纠错(伴随式→BM→Chien→Forney) │ │ ├── mode_decode.rs # 逆向 4 种编码模式 │ │ ├── detect.rs # 定位图案检测 + 采样网格 │ │ └── image.rs # 图像加载 + 二值化 │ ├── encoder/ │ │ ├── mode.rs # 4 种编码模式 │ │ ├── segment.rs # 字符串分段 │ │ └── bitstream.rs # 比特流拼接 │ ├── matrix/ │ │ ├── grid.rs # 模块矩阵 │ │ ├── patterns.rs # 定位/对齐/时序图案 + BCH 码 │ │ ├── placement.rs # 蛇形数据排列 │ │ └── mask.rs # 8 掩码 + 四规则评分 │ └── render/ │ ├── png.rs # PNG 输出 (image crate) │ ├── svg.rs # SVG 输出 │ └── ascii.rs # 终端 ASCII ├── cli/ # CLI 命令行工具 │ └── src/main.rs # clap 参数解析 ├── gui/ # Tauri 桌面应用 │ ├── capabilities/default.json # ACL 权限 │ ├── src/ │ │ ├── main.rs # Windows 子系统入口 │ │ └── lib.rs # 6 个 Tauri commands │ ├── src-frontend/ # React 前端 │ │ └── src/ │ │ ├── App.tsx # 主布局(三栏+底部输入) │ │ ├── components/ # ModePanel / QrPreview / ExportPanel / HistoryList │ │ ├── modes/ # 7 种模式表单 │ │ ├── hooks/ # useQrEncode(防抖+编码) │ │ ├── store/ # Context + useReducer │ │ ├── types/ # TypeScript 类型 │ │ └── utils/ # qrText.ts 文本构造工具 │ └── tauri.conf.json # 窗口 + NSIS 打包配置 ├── web/ # Web 服务 │ ├── Dockerfile # rust-alpine 多阶段构建 │ └── src/ │ ├── main.rs # axum HTTP 服务 │ └── templates/ │ └── index.html # 内嵌 GUI 风格页面 ├── .dockerignore └── Cargo.toml # Workspace: core + cli + gui + web ``` ## 支持规格 | 维度 | 范围 | |------|------| | QR 版本 | 1 ~ 40(21×21 ~ 177×177 模块) | | 纠错级别 | L (7%) / M (15%) / Q (25%) / H (30%) | | 编码模式 | 数字 / 字母数字 / 字节 / 汉字 (Shift JIS) | | 输出格式 | PNG / BMP / JPEG / WebP / SVG / 终端 ASCII | | vCard 字段 | 姓名/电话/邮箱/公司/职位/地址/网址/生日/备注/照片 (10 字段) | | 使用方式 | Library / CLI / GUI / Web API | | 解码 | 从图片识读 QR 码 → 文本(支持旋转矫正) | | 自动版本选择 | 根据数据长度 + 纠错级别 | | Docker 镜像 | ~18MB (alpine) | ## 代码示例 `examples/` 目录包含三个示例: ```bash # 基础编码(默认配置) cargo run --example basic_qr # 高纠错级别(H 级,30% 容错) cargo run --example high_ecc # 自定义配置(固定版本 + 大尺寸 PNG) cargo run --example custom_config ``` 作为程序库使用(编码 + 解码): ```rust use qr_core::qr::{QrCode, QrConfig}; use qr_core::decoder; // 编码:文本 → QR let qr = QrCode::encode("Hello QR!", QrConfig::default())?; qr.to_png_bytes(8)?; // PNG 字节 let svg = qr.to_svg(); // SVG 字符串 // 解码:QR 图片 → 文本 let bytes = std::fs::read("qr.png")?; let result = decoder::decode_image(&bytes)?; println!("解码结果: {}", result.text); ``` ## 发布到 crates.io `qr-core` 可作为 Rust 库被其他项目引用: ```bash cargo add qr-core ``` ## 社区 - [CLI 使用手册](docs/CLI_USAGE.md) — 命令行完整指南 - [贡献指南](CONTRIBUTING.md) — 如何参与开发 - [行为准则](CODE_OF_CONDUCT.md) — 社区规范 - [安全策略](SECURITY.md) — 漏洞报告流程 - [变更日志](CHANGELOG.md) — 版本历史 - [Issue 模板](.github/ISSUE_TEMPLATE/) — Bug 报告 / 功能请求 ## 许可证 MIT License ## 作者 [刘航宇](https://github.com/LHY0125) — 河南理工大学人工智能协会