Show HN: ShadowCat – 通过浏览器中的二维码传输文件
Show HN: ShadowCat – file transfer through QR Codes in a Browser

原始链接: https://github.com/unprovable/ShadowCat

这是一个单文件、离线式的 HTML 工具,旨在通过二维码在设备间传输数据。对于那些无线功能损坏但摄像头和浏览器仍可工作的旧硬件来说,这是一个理想的解决方案。 **工作原理:** * **发送端:** 将文件编码为循环播放的二维码序列。用户可以调整数据块大小、每秒帧数 (FPS) 和纠错级别,以平衡传输速度与稳定性。如果漏掉某些数据块,可手动重新发送。 * **接收端:** 通过摄像头扫描二维码序列。系统会自动追踪已接收的数据块,识别缺失数据,并在传输完成后通过 CRC32 校验文件完整性。 **技术要求:** * **托管:** 由于浏览器安全权限 (getUserMedia) 的限制,该文件必须通过 HTTPS 或本地网络(例如 Python 的 `http.server`)进行托管。 * **性能:** 传输效率受二维码密度和硬件性能限制。典型吞吐量约为 0.8 KB/s。对于性能较差的设备,建议降低 FPS、减小数据块大小并提高纠错级别,以确保成功解码。 这款轻量级工具为无法使用现代无线协议的设备提供了一种稳健的“离线优先”数据迁移方案。

**ShadowCat** 是一款基于浏览器的工具,能够通过二维码实现离线文件传输。该工具由用户 *unprovable* 开发,它将文件分块转换为一系列二维码,并可由另一台设备的摄像头进行扫描。系统包含 CRC 校验功能,以确保数据在重组过程中的完整性。 该项目最初是为了从一台受水损的手机中恢复数据而构建的,目前正在 Hacker News 上受到讨论。社区反馈积极,用户建议了一些改进措施,例如将工具托管在 GitHub Pages 上以便于访问、制作演示视频,以及集成本地大语言模型(LLM)以实现更便携的离线生成。ShadowCat 为基于声音的数据传输方式提供了一种实用的替代方案,为在物理隔离(air-gapped)设备之间传输文件提供了一种可靠的方法。
相关文章

原文

A fully offline, single-file HTML page for moving data between two devices via QR codes — intended for old phones whose radios (BLE, NFC, etc.) arevdead but whose cameras and browsers still work.

  • Generate — encode text into a single QR code.
  • Scan — decode a single QR via the camera.
  • Send file — pick a file, choose chunk size / FPS / ECC, hit Start. Cycles through [header, chunk1…chunkN] forever at the chosen FPS. Pause / Resume / Stop.
  • Start from — begin the loop at a chosen frame index; it then continues forward and wraps back to the header normally.
  • Show frame + Show / / + — display exactly one frame static, for resending a specific missing chunk. The number matches the chunk index shown in the receiver's missing-chunks grid (0 = header).
  • Receive file — start the camera and point at the sender. Header autodetects, progress bar fills in, missing-chunks grid shows which ones haven't arrived yet. When complete, the file's CRC is verified and a Download button appears.
  • Header: QRX1|H|<total>|<filename>|<sizeBytes>|<crc32hex>
  • Data: QRX1|D|<idx>|<base64chunk> (1-indexed)
  • Base64 alphabet has no |, so parsing is just split('|').
  • Receiver tracks chunks by index, ignores duplicates, dedupes header by CRC.

Practical notes for old phones

  • Camera needs HTTPS or localhost — file:// won't grant getUserMedia permission. Serve with python3 -m http.server 8000 and visit http://<your-laptop-ip>:8000/qrcode.html over the local network. iOS Safari additionally requires HTTPS for cross-device access — for a LAN setup, caddy or a self-signed cert helps.
  • If render fails on a frame ("code length overflow"), drop chunk size or drop ECC level.
  • 500 chars × 3 fps ≈ 1.1 KB/s base64 ≈ 0.83 KB/s raw. A 100 KB file is roughly 2 minutes per loop; receiver typically needs 1-2 loops.
  • If old devices struggle to decode: lower FPS, raise ECC to Q, shrink chunk to ~300 chars — produces smaller, less dense QRs.
联系我们 contact @ memedata.com