Skip to content
HN On Hacker News ↗

GitHub - unprovable/ShadowCat: Single file optical file transfer using a browser

▲ 160 points 61 comments by unprovable 2d ago HN discussion ↗

Pangram verdict · v3.3

We believe that this document is fully AI-generated

99 %

AI likelihood · overall

AI
0% human-written 100% AI-generated
SEGMENTS · HUMAN 0 of 2
SEGMENTS · AI 2 of 2
WORD COUNT 317
PEAK AI % 100% · §1
Analyzed
May 22
backend: pangram/v3.3
Segments scanned
2 windows
avg 159 words each
Distribution
0 / 100%
human / AI fraction
Verdict
AI
Pangram v3.3

Article text · 317 words · 2 segments analyzed

Human AI-generated
§1 AI · 100%

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. Tabs

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.

Protocol

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.

§2 AI · 100%

If old devices struggle to decode: lower FPS, raise ECC to Q, shrink chunk to ~300 chars — produces smaller, less dense QRs.