Transferring data using barcodes
In all my years programming, I had never been in a situation where I had to transfer information between devices without using WiFi, Bluetooth, USB, or NFC. But that's exactly what my latest project required.
Requirements
Basically, I needed to transfer information from some air-gapped Windows computers to an iOS device. Normally, this would be accomplished using well-established procedures such as USB flash drives, but this wasn't possible with iOS. In addition, a non-trivial amount of information had to be transferred multiple times a day, so manually retyping in all the data wasn't feasible.
My solution
All the high-bandwidth communication channels were blocked right? No! There were cameras on the device. The solution was obvious: barcodes.
After lots of googling and reading about barcodes, I settled on using PDF417 barcodes for their information density, ease of use and liberal license. The all-familiar QR codes would've worked just as well in most circumstances.
Implementing this was easy. Apple includes a fantastic barcode reader API as part of their AVFoundation framework, and there were JavaScript libraries freely available on GitHub to generate PDF417 barcodes. I settled on this one.
- The input is converted into a base64 string so that anything can be transferred.
- A SHA256 hash is generated and converted into a barcode.
- The data is split into chunks of less than or equal to a constant length, and converted into data barcodes. Each barcode also contains the total number of barcodes and its index, so that the device can reassemble all the barcodes in the correct order.
Benefits
All the data can be transferred without any wired or wireless connections, as long as the iOS device can somehow scan the barcodes. This provides some flexibility, including the ability to print the barcodes out and bring them to another location for scanning.
Any source data can be transferred since everything is converted into base64 before sending. It could also be encrypted, but a way to exchange keys has to be implemented first. I considered making the iOS device generate a public and private key, before transferring the public key to the computer using QR codes and a scanner.
Problems and solutions
This solution certainly wasn't perfect.
Speed, bandwidth, and labor
It's nowhere as fast as the usual wired and wireless methods, and required the user to manually scan individual barcodes. Also, the number of barcodes increases proportionally to the amount of data, potentially resulting in an unreasonable amount of information transfer time.
Scanning the barcodes can be automated if there is a way for the iOS device to send some sort of "scanned" acknowledgement back to the computer. This could be easily accomplished if the iOS device displays these acknowledgements as barcodes on its screen, which are then scanned by a camera (or even a scanner) connected to the computer. A very primitive and slow TCP implementation, but it'll work.
Alternate solution
One idea I thought of was to transfer data over an audio signal. The computer will play an audio signal through the headphone jack, which the iOS device will use as input. This would be similar to how Square's magnetic stripe reader works. Unfortunately, I couldn't find an easy way to generate and play an audio signal in Internet Explorer, and receive and interpret the audio signal in iOS.
Similar projects
After I implemented my solution, I found out that this had been done before. Do check them out too:
- https://github.com/leonjza/qrxfer
- https://volumelabs.net/jumping-the-gap-data-transmission-over-an-air-gap/
Conclusion
Using barcodes to transfer data worked surprisingly well. It's trivial to implement (I wrote both the generator website and the iOS scanning app in a couple of days), can transfer all types of data, and can even use paper as a transmission medium. Although I would definitely recommend using WiFi or Bluetooth instead, barcodes are a respectable alternative.