{"slug": "show-hn-shadowcat-file-transfer-through-qr-codes-in-a-browser", "title": "Show HN: ShadowCat – file transfer through QR Codes in a Browser", "summary": "ShadowCat is a fully offline, single-file HTML page that enables data transfer between two devices by encoding files into a sequence of QR codes, designed for old phones with working cameras and browsers but non-functional radios. The sender encodes a file into chunks displayed as QR codes at a chosen frame rate, while the receiver scans them via camera, tracks missing chunks, and verifies the file's CRC before allowing download. The tool supports adjustable chunk size, FPS, and error correction, with a typical transfer speed of about 0.83 KB/s raw data, requiring one to two loops for a 100 KB file.", "body_md": "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.\n- Generate — encode text into a single QR code.\n- Scan — decode a single QR via the camera.\n- Send file — pick a file, choose chunk size / FPS / ECC, hit Start. Cycles through\n[header, chunk1…chunkN]\nforever 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.\n- 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).\n- 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.\n- Header:\nQRX1|H|<total>|<filename>|<sizeBytes>|<crc32hex>\n- Data:\nQRX1|D|<idx>|<base64chunk>\n(1-indexed) - Base64 alphabet has no\n|\n, so parsing is justsplit('|')\n. - Receiver tracks chunks by index, ignores duplicates, dedupes header by CRC.\n- Camera needs HTTPS or localhost —\nfile://\nwon't grantgetUserMedia\npermission. Serve withpython3 -m http.server 8000\nand visithttp://<your-laptop-ip>:8000/qrcode.html\nover the local network. iOS Safari additionally requires HTTPS for cross-device access — for a LAN setup,caddy\nor a self-signed cert helps. - If render fails on a frame (\"code length overflow\"), drop chunk size or drop ECC level.\n- 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.\n- If old devices struggle to decode: lower FPS, raise ECC to Q, shrink chunk to ~300 chars — produces smaller, less dense QRs.", "url": "https://wpnews.pro/news/show-hn-shadowcat-file-transfer-through-qr-codes-in-a-browser", "canonical_source": "https://github.com/unprovable/ShadowCat", "published_at": "2026-05-22 11:11:43+00:00", "updated_at": "2026-05-22 12:13:59.285572+00:00", "lang": "en", "topics": ["developer-tools", "open-source", "products"], "entities": ["ShadowCat", "QRX1"], "alternates": {"html": "https://wpnews.pro/news/show-hn-shadowcat-file-transfer-through-qr-codes-in-a-browser", "markdown": "https://wpnews.pro/news/show-hn-shadowcat-file-transfer-through-qr-codes-in-a-browser.md", "text": "https://wpnews.pro/news/show-hn-shadowcat-file-transfer-through-qr-codes-in-a-browser.txt", "jsonld": "https://wpnews.pro/news/show-hn-shadowcat-file-transfer-through-qr-codes-in-a-browser.jsonld"}}