Show HN: ShadowCat – file transfer through QR Codes in a Browser

https://github.com/unprovable/ShadowCat

Comments

divanMay 22, 2026, 2:04 PM
This method of animated QR data transfer is quite efficient with fountain codes. I had PoC implementation back in the day - Txqr [1] [2]

[1] https://divan.dev/posts/animatedqr/

[2] https://divan.dev/posts/fountaincodes/

Recently I rewrote it in Dart/Flutter and finally implemented RaptorQ codes (way more efficient than Luby used in original Txqr). Testing it internally now, prepareing Appstores/GooglePlay/Web deployment and new article.

kigMay 22, 2026, 6:09 PM
This is cool and minimalistic!

I've been noodling on https://qr-send.com which is a slightly more polished version of the "erasure fountain codes + stream of QRs"-idea, inspired by divan's Txqr posts but using Wirehair FEC for the fountain code (basically: you receive ~file size bytes via QR codes and it magically assembles them into the source file regardless of missed codes).

It's an offline-first progressive web app and there are native & wasm builds for the sender. The browser-to-browser transfer falls up to WebRTC when possible because 30 MB/s over wifi beats a 100 kB/s QR stream. The QR scanner is a heavily-optimized WASM build of zbar, scanning at 60 fps on mobile & multiple QRs per frame (but it's finicky! Work in progress.)

cl3mischMay 22, 2026, 6:14 PM
That sounds amazing!

The WebRTC "fallback" basically means the QR code is just a handshake when both devices are on the same network?

kigMay 23, 2026, 9:15 AM
The handshake details are passed alongside the data so that if a direct connection is successful, the network races the optical transfer.
dschepMay 22, 2026, 6:26 PM
This looks like a nice polished implementation of the idea, but when I try and use it, I get to "file complete" but then.. nothing? And I see no way to report a problem or bug.
kigMay 23, 2026, 11:23 AM
Thanks for trying it, sounds like a bug I've been running into for a couple days where the wasm stream decoder does a bad memory access. I made some buffer lifetime fixes, next up a more complete stress test and fuzzing to see if I can pinpoint it.
dschepMay 25, 2026, 11:23 PM
It's working for me now! Multiple QR codes at once is kinda wild.
rao-vMay 23, 2026, 7:09 AM
What is the fastest you can transfer data from ~10 meters away using a modern phone front camera and screen? Surely 100 kB/s is slow?
kigMay 23, 2026, 9:46 AM
Depends on the zoom. With this setup you can transfer about 0.1 B/s per pixel of 60 FPS video. So a 65" screen and 1080p camera at 10 meters away would max out at 2 kB/s with the normal lens (26mm equiv) or 45 kB/s with the tele lens (120mm equiv.)

I'm cooking something faster but depends on the job situation and funding whether I have time to spend on it.

Napkin math: QR codes encode 0.75 bits per module, each module needs about 3 pixels of camera resolution, and the temporal resolution is quite dodgy as well, maybe 0.25 * min(cameraHz, screenHz). So if everything is perfect, 44 kB/s at 60Hz per a 500x500 pixel patch. I've seen ~250 kB/s when a 1920x1080@60 transfer is working well. At 4k@30, you might reach 0.5 MB/s. If you throw in the 2x subsampled UV channels to transfer data as well, you might get an extra 50%.

unprovableMay 22, 2026, 11:13 AM
Single page file transfer using QR Codes and a browser. Sending device loads a file into the page, gets chunked. Receiver gets all the chunks through a camera, tosses lightly and reassembles, CRC to garnish. Designed to push data from an old phone that had broken comms after it took a swimming lesson in a coffee mug, it's been quite handy.
HanClintoMay 22, 2026, 2:52 PM
If the phone had broken comms, how did you get the code onto the phone to run?
rmunnMay 23, 2026, 4:47 AM
Not OP, but I'm guessing by running the code on itself, i.e. turning the code into a QR code (or a series of them), then scanning those QR codes on the phone and reassembling them using a text-editing app on the phone.
Chant-I-CRWMay 22, 2026, 4:15 PM
In ye olden days we used cables to sync all of our apps and data to our phones.
wongarsuMay 22, 2026, 4:34 PM
But why not move the data over that cable? Some kind of iOS thing that made that more complicated than pushing an app to the phone?
unprovableMay 23, 2026, 6:47 AM
With great difficulty...
harkaniemiMay 23, 2026, 7:33 AM
This is wild. I made an identical program 24 hours ago. Mine just transfers text files
harkaniemiMay 24, 2026, 10:03 AM
Okei, I tested yours and it works. I would change one thing: You could start receiving chunks at any point. I had total chunk amount and chunk order in every chunk, so you can start receiving at any point.
pajamasamMay 22, 2026, 12:25 PM
Interesting idea! A demo video would be great :)
anhldbkMay 22, 2026, 12:38 PM
I also implemented a static web with that idea: https://github.com/anhldbk/get-beam
lukew3May 22, 2026, 12:07 PM
You should turn on github pages so we can see it live. Seems cool but I’m not at my pc rn
aliirzMay 22, 2026, 3:30 PM
very nice list! Can I suggest adding my https://phntm.sh as well? itis a zero-knowledge file transmission system.
LevitatingMay 22, 2026, 5:59 PM
I am not the author, you could leave a comment on the gist instead.
unprovableMay 26, 2026, 2:38 PM
Update - put it on a site for folk to use: https://shadowcat.online/
MattCruikshankMay 22, 2026, 12:52 PM
I've wanted to use this for an air-gapped communication device.

I have a device with a camera and a touch-screen that only uses capacitive charging. I type a message. Bytes are encrypted. I hit send. QR codes flash on my screen. I use my PC or my normal phone to receive the encrypted bytes, and transmit them to you. You have the same device. You have your PC or phone flash encrypted QR codes. You use your device to receive, and then decrypt.

I've daydreamed about also buying several different hardware random noise generators. XOR all of their bits together. Save a huge one time pad to each of our devices. And then also use public key crypto on top of it.

I'm not really sure why I want this. But, it's my answer for how to reduce attack surface as much as possible, and have truly secret messages.

reaperducerMay 22, 2026, 2:52 PM
I have a device with a camera and a touch-screen that only uses capacitive charging. I type a message. Bytes are encrypted. I hit send. QR codes flash on my screen. I use my PC or my normal phone to receive the encrypted bytes, and transmit them to you. You have the same device. You have your PC or phone flash encrypted QR codes. You use your device to receive, and then decrypt.

Congratulations. You just invented IrDA: https://en.wikipedia.org/wiki/IrDA

MattCruikshankMay 22, 2026, 6:27 PM
I specifically want this device to have no input or output hardware that could be used without my knowledge. IrDA could absolutely be used without my knowledge.
reaperducerMay 22, 2026, 10:45 PM
IrDA could absolutely be used without my knowledge.

Having actually used IrDA on Sony, Nokia, and Ericsson devices, no it couldn't.

In the real world, two IrDA devices have to be very specifically aligned, and also brought within just a few inches of each other. There's no way data transfer would happen without your knowledge.

MattCruikshankMay 23, 2026, 2:47 AM
I blame the intentionally cheap receiving optics. Researchers have reconstructed a TV signal from a hotel room with closed blinds, by very accurately measuring the ambient light intensity of the room (as shown on the blinds.)

Knowing that, I doubt that someone with even moderate funding would have difficulty receiving a signal from any of the transmitters you mention.

But, in all honesty, if you put a physical cap on the transmitter and receiver, maybe I'm wrong.

But in the other hand, none of the devices I currently own have one of your transmitters, and they all have screens and cameras, so...

Thanks for the dialogue and for sharing your experiences.

unprovableMay 23, 2026, 9:40 AM
So two parts to a reply - first is, you don't need the encryption per se, but you can add that in the case that you give it some key and then it's encrypted. I don't see the value unless you're using this to generate frames for a video, which isn't current functionality but totally doable.

Second part, Charlie Bennet said "the only entropy source is one you can trust" and the best entropy source is quantum fluctuations, so we built a fully open source phase diffusion QRNG at Quantum Village and released it. Link: https://github.com/QuantumVillage/EntropyLoop

skinfaxiMay 22, 2026, 1:28 PM
> I have a device with a camera and a touch-screen that only uses capacitive charging. I type a message. Bytes are encrypted. I hit send. QR codes flash on my screen. I use my PC or my normal phone to receive the encrypted bytes, and transmit them to you. You have the same device.

Why do you need a separate device for this and not just an airgapped computer?

MattCruikshankMay 22, 2026, 1:38 PM
Me, in my life, I have a PC that's connected to the internet. I have a phone that's connected to the internet.

I want another device, which I imagine to be a Pi or Esp32 or something with a camera and a touchscreen display, and capacitive charging. After I program it and give it the public/private keypair and the OTP, I imagine physically breaking off a USB port, or sealing one with some hardening resin.

I don't want an entire airgapped computer. Maybe you do, that's fine. For me, I'd love it to be a credit-card sized doodad.

hootzMay 22, 2026, 12:13 PM
I love this type of stuff. Some years ago I did something similar, but instead of QR Codes it used a convoluted mess of audio frequency modulation to send data through sound between devices. This is much more practical if you have two cameras.
xnxMay 22, 2026, 12:40 PM
> a convoluted mess of audio frequency modulation

Like a modem

hootzMay 22, 2026, 1:05 PM
I guess lmao, but much more rudimentary, less reliable and with loads of issues, as it had to blast piercing sounds through a speaker and then capture those with a microphone. But it was pretty cool when it worked!
skinfaxiMay 22, 2026, 1:33 PM
Did you explore using frequencies outside the range of human hearing?
reaperducerMay 22, 2026, 2:54 PM
Did you explore using frequencies outside the range of human hearing?

Amazon had modems very much like this in its little buttons that you could stick to your refrigerator and automatically order different items. When setting up the device, you could only hear the little clicks as it turned on and off.

I loved the technology. Hated that the prices changed all the time and you never knew what price you were going to pay ahead of time.

hootzMay 22, 2026, 1:42 PM
No, but that's a cool idea. I think the main problem is that consumer hardware usually gets kinda inconsistent outside our hearing range.
deletedieMay 22, 2026, 1:58 PM
Apple uses this approach when pairing some devices for verification e.g. setting up HomePods using an iPhone
msafi04May 24, 2026, 5:07 AM
I love the focus on giving a second life to old hardware. We often talk about 'local-first' for privacy, but this shows how local-first is also great for hardware longevity. It’s refreshing to see a tool that doesn't require a cloud connection or a functional Bluetooth stack to be useful.
alex_suzukiMay 22, 2026, 12:54 PM
Cool stuff. I’m fond of the “single HTML file” deployment option.
unprovableMay 23, 2026, 6:39 AM
Cheers!
tripflagMay 22, 2026, 12:42 PM
Cool! Out of curiosity, since qr-codes can contain binary data -- rather than base64, have you tried inserting the file as-is? That way you could do away with the ASCII separator and have a binary header as well. This would spend less frames for the same amount of data, but I'm not sure if it would be computationally cheaper. The other alternative would be the alphanumeric mode of qr-codes, but then you lose lowercase.
davidcollantesMay 23, 2026, 3:32 PM
Is there a client that needs to be used to be able to receive files this way? I tried the dedicated QR reader on my iPhone, and the Camera app, and couldn’t get it to assemble the chunks. It will show the encodings one after the other, but nothing else.
hoansdzMay 22, 2026, 12:33 PM
I once heard someone create a QR code scanner to retrieve gigabytes of data, but the biggest problem is that cameras aren't powerful enough to handle it all. Essentially, the QR code needs to be downloaded to the device for loading; relying on the camera to retrieve it is very difficult. Am I wrong about this project? What's your solution?
bensyversonMay 22, 2026, 1:56 PM
I've done a POC with the native QR reading code on iOS. The short answer is: it's not a problem at all, and you can drive very large QR codes for more efficient transfer.
rirzeMay 22, 2026, 3:58 PM
You could also do it the menial way; create multiple QR codes that can connect together. Not very practical for everyone except the very-motivated.
0cf8612b2e1eMay 22, 2026, 4:03 PM
Why not record with a standard high quality webcam and do the QR processing later? That’s how I would exfiltrate a large volume of data.
thedougdMay 22, 2026, 12:58 PM
I've done this exact approach before. It's a good way to exfiltrate data. Post the software on GitHub pages, or a popular CDN that co-hosts other shared libraries and you've got a very difficult to block method.

Really goes to show that it's very difficult to stop a motivated and informed actor.

skinfaxiMay 22, 2026, 1:30 PM
If you can connect to Github pages couldn't you exfil that way? This takes 2 mins for 100KB.
thedougdMay 22, 2026, 4:26 PM
Not quietly. Uploads are commonly monitored by data loss prevention (DLP) solutions, especially when MITM is being used for corporate proxy.

Downloading a tiny JS from a CDN, or accessing a GitHub page is mostly noise, especially if obfuscated well.

skeptic_aiMay 22, 2026, 2:42 PM
Npm install qr-made-up-name Can show qr in console. How do you stop that?
thedougdMay 22, 2026, 4:29 PM
I'm likely being overly specific, but blocking npm downloads, installation on corporate devices, etc is trivial in a restrictive corporate environment.
encomMay 22, 2026, 4:45 PM
We used to be able to send arbitrary files between phones using Bluetooth. Where did that go? We had a bit of a music piracy ring going at school for a time. Good times.
okandshipMay 23, 2026, 7:55 AM
animated qr + erasure coding is a neat fit here. the interesting ux question is how clearly the receiver shows progress and recovery
unprovableMay 23, 2026, 9:38 AM
There is a toggle where you can show what chunks have been received. This is also where the 'show specific chunk' function comes in... the receiver can see "oh, I'm only missing chunk 125, so just show me that" etc. etc.
m_m_carvalhoMay 22, 2026, 9:07 PM
Clever use of QR for file transfer. How does it handle larger files? Is there chunking + reassembly on the receiving end?
jaysyrkMay 22, 2026, 4:41 PM
I created a file optimizer, one single file. I was wondering if i could work with you to integrate that into your project. Lmk!!
acrophiliacMay 22, 2026, 2:49 PM
What's the length limit? I tried pasting some text and got this message: code length overflow. (85700>18672)
unprovableMay 23, 2026, 6:39 AM
QR code has limits, use the file transfer to chunk it. :)
teravorMay 24, 2026, 1:19 AM
i feel like it should be possible to push this to extremely high bandwidth.

use a 1D code variant with very high FPS to work around the rolling shutter.

villgaxMay 22, 2026, 12:19 PM
What would make this truly portable is being able to generate this consistently with a short prompt and generate with a local LLM. That way no network calls or file hash can prevent this
econMay 22, 2026, 9:07 PM
Finally real one way data transfer.
Aleesha_hackerMay 22, 2026, 3:48 PM
Let Ai help you research not write keeps the content human and original
TimoKnMay 25, 2026, 9:20 PM
[flagged]
HozefaKanchwalaMay 22, 2026, 4:43 PM
[flagged]
dsewell2707May 22, 2026, 7:03 PM
[flagged]
zerocloudpdfMay 22, 2026, 3:52 PM
[flagged]
MarStudioMay 22, 2026, 1:06 PM
[dead]
fizza_pizzaMay 22, 2026, 2:45 PM
[flagged]
MeherunJessiMay 22, 2026, 9:34 PM
[dead]