Xfer is a utility to allow out-of-band sending of arbitrary data, using animated GIF QR-codes and webcams.
- Clone the repository
- Run
pip install -r requirements.txt
(may bepip3
, in place ofpip
, depending on your OS).
The workflow looks something like this:
- Alice runs Xfer on their local machine, as such:
cat 'This is a message to send' | python3 xfer.py write --outfile send.gif
- Alice opens
send.gif
and records the output on a mobile device. - Alice send a message, via a third party service, such as Signal, to Bob.
- Bob runs
python3 xfer.py read
on his laptop. - Bob plays the recording of the animated gif, and captures the video on their laptop's webcam.
- Once Xfer has captured all the individual frames, it will output the original message on Bob's screen.
-
xfer write
breaks the source message down into chunks. By default these are 256 byte chunks. This is not supported as a flag, because the relationship between chunk size and QR code dimensions are not clear. The values can be seen at the top of thexfer
script, but should not be changed unless you know what you are doing! -
Each chunk is then encoded to a static QR code, with it's frame number for reassembly.
-
A keyframe is added to the start of the sequence, to instruct the receiving application on the number of frames it should expect.
-
The collection of static images is then compiled into an animated GIF.
-
On the receiving side, a loop watches for and decodes QR-codes.
-
The keyframe, which may arrive out of sequence, determines how many unique frames are expected.
-
Having received all frames, the loop will exit and the data packet is reassembled.
- Xfer was not written to be secure. It can be used as part of a secure workflow, if PGP keys are shared beforehand and the data transmitted is encrypted.
- Xfer does not compress data; repeated data will be encoded as is.
- (optionally) gzipping, or otherwise compressing the original data will reduce the amount of data required to be transmitted.
- Checksum of the source data, and storing this value in the keyframe, will allow us to verify the received data has not been tampered with or corrupt in transit.