Transfer Files Without Wi‑Fi or Bluetooth Using Screen‑Flashing QR Codes
Decimen Optical Transfer lets two devices exchange files by flashing QR‑code streams from a screen to a camera, eliminating the need for Wi‑Fi, Bluetooth or shared networks, and achieves up to 186 KB/s with a lightweight pure‑Web implementation.
Background and Motivation
A developer, frustrated by intrusive ads and unreliable streaming, wanted a simple way to copy MP3 files between phones without requiring the devices to share a network. The key requirement was that the two phones could operate independently of any Wi‑Fi or Bluetooth connection.
How Decimen Works
Decimen Optical Transfer displays a rapidly flashing QR‑code stream on the sender’s screen (e.g., https://localhost:5173/send/) while the receiver opens a Vite‑served URL ( https://:5173/receive/) and points its camera at the screen. After a few seconds the sender shows “Transfer Complete!” and the received file passes a hash check.
Typical transfer speed: ~129 KB/s when the sender is handheld.
Optimized: 128 KB/s handheld, 186 KB/s when the sender is placed steadily.
A 2 MB image transfers in a few seconds.
Technical Core – Fountain Codes
The main challenge is the one‑way nature of a screen‑to‑camera link: the receiver cannot tell the sender which frames were missed. Traditional approaches replay all frames, causing long delays when a frame is lost. Decimen solves this by using Fountain Codes:
The sender never transmits raw file chunks directly. Each frame contains an XOR of a pseudo‑random subset of all chunks, derived deterministically from the frame index and following a Robust Soliton Distribution.
The receiver only needs to collect roughly K × 1.15 distinct frames (where K is the total number of chunks) in any order to reconstruct the file, similar to peeling an onion.
Advantages:
Lost frames only waste time; they do not corrupt the transfer.
Sender and receiver frame rates need not be synchronized.
The receiver can start decoding at any point by simply pointing the camera at the screen.
Implementation Pitfalls
4.1 Browser Engine Differences
JavaScript engines implement Math.log slightly differently. Because Fountain Codes require identical bit‑level distributions on both sides, mismatches between V8 and JavaScriptCore cause silent failures. The solution is to implement a deterministic log function that follows the IEEE‑754 specification.
4.2 iOS Camera Quirks
iOS silently reports a frame rate of 30 fps even when frameRate: {ideal: 60} is requested. Using {exact: 60} forces a true 60 fps capture (at 1280‑pixel width), and a fallback check with getSettings() is required.
4.3 Zombie Callbacks
The requestVideoFrameCallback chain persists across stream lifecycles, so each stop/start creates a leaked “zombie” capture loop because there is no generation counter.
4.4 Misleading Progress Bar
The LT algorithm’s peeling step is a post‑cascade process: most of the time the UI appears stuck, then suddenly jumps to 100 %. The progress bar must track the number of collected frames, not the number of solved blocks.
4.5 QR Error‑Correction Level
QR code ECC and Fountain Codes address different failure modes (damage vs. erasure). Decimen chooses the minimal QR error‑correction level (L) because the per‑frame Fountain Code already provides robust erasure protection.
Configurable Parameters
Both sender and receiver expose tunable settings:
payload size : 512 KB – 2 MB (selects file size).
tx fps : default 24 (each frame occupies at least two display refresh cycles).
bytes / frame : 1465 bytes for QR version 27; 2953 bytes for version 40 (usable at close range).
error correction level : L (see section 4.5).
display size : controls QR code physical dimensions.
Receiver settings include capture width , capture fps , and decode worker count .
Related Projects
mohankumarelec/airgapped-qr-code-transfer : Browser‑based QR file transfer with compression and sequential chunks.
divan/txqr (2018): Go implementation of animated QR + Fountain Codes, with articles explaining why Fountain Codes outperform simple looping.
sz3/libcimbar : High‑density color code designed specifically for this channel, surpassing QR.
Demo and Open‑Source Information
The demo shows a phone aimed at a laptop screen, transferring an image in a few seconds.
Project repository: https://github.com/bashalarmistalt/decimen-optical-transfer (MIT license, 375+ stars). The stack uses node-qrcode and zxing-wasm. To run: npm install → npm run dev.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Black & White Path
We are the beacon of the cyber world, a stepping stone on the road to security.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
