Underlabs Lab · Working prototype

Moving data through animated QR codes

How can a browser send a file to an iPhone through a screen and camera, without a network connection between the two? QRDataTransfer explores an optical channel that must cope with missed frames, duplicates and corrupted data.

QRDataTransfer

From screen to verified bytes.

The demonstration shows an iPhone scanning a browser’s QR sequence, recovering blocks, verifying the result and opening the received video containing the Underlabs logo.

  1. Rust prepares source blocks and repair symbols.
  2. The browser displays animated QR frames.
  3. Vision decodes; the Swift receiver reconstructs the data.
  4. SHA-256 verification gates the file preview.

On-screen measurements describe this session. They are not a throughput promise.

A working browser-to-iPhone optical data-transfer prototype. The receiver reconstructs the data, verifies its integrity and opens the transferred video.

A browser, a Rust sender and an iPhone

A local Rust service accepts text or a file, splits the bytes into blocks and creates protocol frames. The browser displays them as an animated sequence of standard QR codes. On the iPhone, iOS Vision decodes the camera images; a Swift receiver validates the binary frames and reconstructs the payload. The browser is the display interface, with the Rust service generating the transfer.

Why fountain recovery matters

A camera will not capture every displayed code. The sender first transmits source blocks, then deterministic LT fountain repair symbols that combine blocks using XOR. The receiver uses these equations to recover missing blocks from enough usable symbols, rather than waiting for one particular frame to repeat. QR error correction helps within a single image; fountain recovery addresses loss across the sequence. It still needs sufficient independent, valid data to finish.

Reconstruct first. Verify before opening.

The receiver checks frame structure, session information and CRC32, rejects damaged or incompatible frames and ignores duplicate symbols. Once the source blocks are recovered, it reassembles the original bytes and compares their SHA-256 digest with the manifest. Only verified content is previewed: text and supported images directly, or video through the system player. Integrity checks detect corruption; they do not independently establish the sender’s identity.

What was tested

The October 20, 2026 component test run passed 41 Rust tests across the protocol core, command-line sender, QR image library and channel simulator. Coverage includes deterministic framing, fountain recovery, loss and reordering, duplicates, corruption rejection, authentication checks, whole-payload hash rejection and independent QR image decoding. Cross-language golden vectors define agreement between Rust and Swift. The supplied iPhone recording shows a successful reconstruction, verification and video playback; it is a demonstration, not a repeatable throughput benchmark.

Current prototype limits

Camera focus, lighting, display refresh, QR density and file size affect scan time and completion. Video transfer can be slow, and no general physical throughput or maximum demonstrated file size is claimed here. The protocol’s 64 MiB limit is a software boundary, not a verified camera-transfer result. Optional shared-key HMAC authenticates frames but does not encrypt the payload or prevent replay of a complete valid session. This is a working engineering prototype, not a production file-transfer service.