I’ve got a theory that an animated high-resolution barcode is a a workable mode of communication for sending data across an air gap. The host machine displays barcodes, say once a second, and client software on a phone or laptop off the air-gap reads and decodes the barcodes. In this manner, a large amount of compressed data can be transmitted over the air with significant error-correction.
A version 40 QR code with low error-correction can transmit 4296 alphanumeric characters, dropping to 1852 characters with high error-correction enabled. Either of those is an excellent rate for data transmission.
Clearly this isn’t suitable for high-security envionments as it assumes the user has access to a device with a camera and (as we’ll see) bootstrapping requires the host machine itself to have a webcam. Otherwise it’s a fairly interesting problem to solve.
One issue is that coming by a fully-fitted QR code generating library on an air gapped network might be troublesome. The minimised version of qrcode.js weighs in at just under 20kb, which is a bit too much to type out by hand.
However, I think the process can be trivially bootstrapped using a small, simple javascript application running on the host machine which uses the machine’s webcam to receive burst of data in the form of colours, representing binary data. The data can then be translated back into ascii text.
Currently, using a simple client only 2kb in size, I can receive data at the rate of about 1 ascii character per second. I expect that with some simple compression I can improve this figure, but my priority is currently the simplicity of the bootstrap code, which must be typed manually.
The initial encoding is to transmit binary data representing the QR code generation application using the colours red, green and blue, shown full-screen on another device. Red and green represent binary zero and one, whilst blue acts as a buffer to prevent double-counting. This means the client can poll at a faster rate than the sender is refreshing, which allows for fewer transmission errors.
This also allows the data being transmitted to be stored as a video and played full-screen on the transmitting device, in case there’s no internet access on site.
My proof of concept is available on github. The two files bootstrap.html and bootstrap-capture.html show the transmission of the text “Hello, world!”. Browse to bootstrap.html on github pages on your phone, and bootstrap-capture.html on your laptop.
Hold your phone up to your laptop’s camera so the blue field fills the video box on the screen. Click the page on your laptop until “on” appears in the javascript console, then click the blue field on the screen of your phone. Ensure the colour fills the video box as the colours cycle. Once the transmission ends click the page on your laptop again. The words “off” and “Hello, World!” should appear.