QRBridge

📱 离线二维码文件传输系统 V2.0

一个纯浏览器实现的、完全离线的文件传输工具,通过二维码序列在没有网络连接的环境下传输文件。不需要任何服务器,不需要安装软件,仅需浏览器和摄像头。

✨ 特性

🚀 快速开始

1. 依赖库

项目依赖以下 JavaScript 库,需要手动下载到 js/ 文件夹:

库文件 用途 下载地址
pako.min.js 压缩/解压 (zlib) https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.0/pako.min.js
qrcode.min.js 二维码生成(发送端) https://raw.githubusercontent.com/davidshimjs/qrcodejs/master/qrcode.min.js
localforage.min.js 本地存储(接收端) https://cdn.jsdelivr.net/npm/localforage@1.10.0/dist/localforage.min.js
index.min.js 二维码扫描(接收端,ZXing) https://cdn.jsdelivr.net/npm/@zxing/library@0.21.3/umd/index.min.js

Base45 编解码已内置于 HTML 中,无需额外文件。

2. 文件结构


离线文件二维码传输系统/
├── send/                    # 发送端程序
│   ├── send.html          # 发送端主文件
│   └── js/                # 发送端依赖库
│       ├── pako.min.js    # 压缩库
│       └── qrcode.min.js  # 二维码生成库
└── receiver/                    # 接收端程序
    ├── receiver.html      # 接收端主文件
    └── js/                # 接收端依赖库
        ├── index.min.js   # ZXing二维码扫描库
        ├── localforage.min.js # 本地存储库
        └── pako.min.js    # 解压缩库	
	

3. 使用步骤

发送端(电脑):

  1. 用浏览器打开 send.html
  2. 点击「选择文件」选取要传输的文件
  3. 调整分片大小(默认 1200 字符,可增可减)
  4. 点击「生成二维码」
  5. 使用键盘方向键或鼠标滚轮切换二维码,按顺序展示给接收端扫描

接收端(手机/另一台电脑):

  1. 用浏览器打开 receiver.html
  2. 点击「开始扫描」并授权摄像头权限
  3. 对准发送端屏幕上的二维码,按顺序扫描所有数据分片(最后扫描文件名分片)
  4. 扫描完成后自动重组文件,点击「下载文件」保存

🔧 技术细节

整体流程

发送端:
文件 → 读取为 ArrayBuffer → pako.deflate (level 9) 压缩 
    → Base45 编码整个压缩数据 → 按字符数分片 
    → 每个分片包装成 JSON {i, t, h, f, d} 
    → 生成二维码图片 → 显示并支持导航

接收端:
扫描二维码 → 解析 JSON → 校验 CRC32 → 存储分片(IndexedDB)
    → 检测是否收齐所有数据分片和文件名分片 
    → 自动拼接 Base45 字符串 → Base45 解码 
    → pako.inflate 解压 → 创建 Blob 下载

分片数据结构

数据分片 (t 字段不存在或为 'data'):

{
  "i": 0,            // 分片索引(从0开始)
  "t": 5,            // 总分片数
  "h": "abc12",      // CRC32 校验码(536进制)
  "f": "x9k2m",      // 文件指纹(5位随机字符串,标识同一文件)
  "d": "ABCD..."     // 分片数据(Base45 编码的片段)
}

文件名分片 ("t": "fn"):

{
  "t": "fn",         // 类型标识
  "f": "x9k2m",      // 文件指纹
  "n": "JUU5JTlG...",// Base64 编码的文件名(支持中文)
  "s": 102400,       // 原始文件大小(字节)
  "ts": 1712345678,  // 时间戳
  "tc": 5,           // 数据分片总数
  "h": "def34"       // CRC32 校验(对除 h 外的字段计算)
}

为什么选择 Base45?

项目中 Base45 采用纯 JavaScript 实现,符合 RFC 9285 标准。

CRC32 校验

使用 pako.crc32 保证与 pako 库一致,备用实现兼容无 pako 环境。

发送端导航与交互

接收端自动重组与存储

压缩优化

const compressed = pako.deflate(new Uint8Array(fileBuffer), { level: 9 });

📊 性能与容量

文件大小 压缩后大小 Base45 长度 分片数 (1200字符/片) 建议
100 KB ~60 KB ~90 KB 75 数据 + 1 文件名 快速
500 KB ~300 KB ~450 KB 375 + 1 可接受
1 MB ~600 KB ~900 KB 750 + 1 较慢,建议调大分片
≥ 2 MB ≥1.2 MB ≥1.8 MB ≥1500 + 1 不推荐(二维码数量过多)

实测:2KB 文件约需 2-3 个二维码,5MB 文件约需 400-500 个二维码(扫描耗时约 15-20 分钟)。

🛠️ 浏览器兼容性

浏览器 发送端 接收端 备注
Chrome 80+ 最佳体验
Edge 80+ Chromium 内核
Firefox 75+ 完全支持
Safari 14+ 需授予摄像头权限
移动端浏览器 ✅ (生成) ✅ (扫描) 接收端扫码效果好

📂 代码结构说明

send.html 核心函数

receiver.html 核心函数

❓ 常见问题

Q: 扫描时提示“找不到摄像头”?
A: 请确保已在浏览器权限设置中允许摄像头访问,且设备有摄像头硬件。部分浏览器需要 HTTPS 环境(本地 file:// 协议也可能工作,但推荐使用本地 HTTP 服务器)。

Q: 为什么需要 Base45?直接用 Base64 不行吗?
A: Base64 膨胀率更高,同样大小的二维码可容纳的有效数据更少,分片数量更多。Base45 是专为二维码设计的标准,能提高约 10% 的传输效率。

Q: 分片大小设置为多少合适?
A: 推荐 1200 字符。过小会导致二维码数量增多,过大会超过 JSON 长度限制(≥1800 字符可能无法生成二维码)。若生成时提示 JSON 过大,请减小分片大小。

Q: 接收端能兼容旧版本(Base64 编码)的二维码吗?
A: 不兼容。此版本使用 Base45 编码,与之前的 Base64 版本数据格式不同。如果之前有旧二维码,请用旧版接收端。

Q: 为什么接收端没有“重组文件”按钮?
A: 为了提高自动化程度,接收端检测到所有分片完成后会立即自动重组,无需手动点击。重组成功后显示下载按钮。

📝 许可证

MIT License。欢迎自由使用、修改、分发。

🙏 致谢

⭐ 如果这个项目对您有帮助,请给个Star! 您的支持是我们持续改进的动力!

注意: 本项目仍在积极开发中,欢迎反馈和建议!

最后更新: 2025年12月 版本: 1.0