QArt codes, the better way to put picture in a QR code

[Russ Cox], current Googler and formerly of Bell Labs, posted an awesome guide to putting images in a QR code. Unlike this terrible attempt I wrote last August, [Russ]’s method does much more than simply paste an image into a QR code and hope the error correction passes. This new method generates a unique URL to be encoded for each QR code. In other words, the embedded image is actually part of the QR code and not just a copy and paste attempt.

The basis of [Russ]’ hack is the ability to change the message contained in a QR code to be made of either ASCII/UTF-8 or decimal numbers coded as binary. By appending an anchor tag (i.e. http://swtch.com/pjw/#123456789...) to the URL that will be encoded, [Russ] can change a whole bunch of pixels in a QR code to make just about any image.

With a few tricks like building new Reed-Solomon encoded blocks, [Russ] can change where in the pixels required by the QR code are placed. This allows for the full-width image of PJW’s binary likeness to be displayed in the QR code.

[Russ] put up a QArt coder that allows anyone to put a pixelated image in any QR code. [Luke Shumaker] (thanks for sending this in, [Luke]) took this tool and put the ‘ol skull ‘n wrenches inside a QR code pointing to hackaday.com. Very nice work from [Russ], and puts my work to shame. I’ll go cry in a corner now.

From a coding theory standpoint, I’ll point out that this isn’t so very different (informationally) from pasting the logo into the QR Code.

Both of them sacrifice a modicum of robustness to achieve the graphic. The pasted-in logos do this by destroying some data, while this new approach does it by forcing the code to represent a much larger string.

Simple example. Let’s say you wanted to change ‘hackaday.com’ to ‘backaday.com’ You would do this by changing the ‘h’ to a ‘b’.

‘h’ has a binary ascii value of 01101000 and ‘b’ has a binary ascii value of 01100010. You can change the second-to-last 0 in the ‘h’ to a 1, but since you can’t change the 1s to 0s, you’re left with ‘jackaday.com’

That’s a simplistic explanation, but you get the point. Also, i’m not even going to check jackaday to see see if it exists.

No that example is too simplistic. The original hackaday QR hack worked despite a chunk of the code being obscured by a picture. Individual squares are not equal to individual bits, but the output of some forward error correction algorithm.

I theorize it should be equally possible to fool the reader into flipping 1s to 0s as it is 0s to 1s, but there is a limit to how many bits can be flipped.

Just getting a reader to point a server you have control of would be doing well. Once there, it doesn’t matter what the page requested actually is as you can just create a soft link to suit the hack.