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.

Black & White Path
Black & White Path
Black & White Path
Transfer Files Without Wi‑Fi or Bluetooth Using Screen‑Flashing QR Codes

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 installnpm run dev.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptQR codeViteFountain codesScreen streamingWeb transfer
Black & White Path
Written by

Black & White Path

We are the beacon of the cyber world, a stepping stone on the road to security.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.