#0018: Creating and utilising QR Codes

#0018: Creating and utilising QR Codes

image of a QR code

What is a QR code?

QR codes are a type of barcode. Barcodes are a visual representation of digital (or binary) information. They are designed to be easily understandable by machines. Barcodes enable machines to do useful operations that involve interacting with the physical objects, that the barcodes are placed on. Such as sorting or counting large volumes of items accurately. For example, with packages at a mail depot, or product inventory at an automated warehouse or factory.

A QR code (or Quick Response Code), is a type of 2 dimensional barcode, otherwise known as a matrix barcode. All this means is that it represents it’s binary information visually across two axis (x and y). It does this by plotting black (1) and white (0) squares on a grid. Matrix barcodes are an evolution on the iconic one dimensional barcodes; which represent their binary information in a single array of black lines and white spaces (i.e. columns), that denote their ones and zeros respectively.

It should be noted that there are numerous different types of barcodes (both 1D and 2D) in use today. Each one is specialised to their specific applications. These specialisations manifest themselves with variations in visual design (e.g. with markers for orienting scanners with different protocols); barcode size, reflecting how much data they need to represent/encode; and data encoding ability; i.e. what type of data the barcode image represents (typically: numbers, or ASCII symbols).

The most obvious difference between one dimensional (array) and two dimensional (matrix) barcodes, is the addition of a Y dimension of information. This addition allows for a greater density of information to be stored, however it also requires more sophisticated tooling to actually read the data from the barcodes themselves. The most notable hardware difference in this regard is that one dimensional barcodes use a simple laser line scanner, whereas matrix barcodes require a camera module. Because of this, you typically can not read any matrix barcodes with hardware designed for 1D barcodes, however in many cases (providing that the software allows for it), you can use a matrix barcode scanner (e.g. smart phone) to read information from 1D barcodes.

Additionally, I make assumption that on a barcode: black denotes a one in binary and white a zero. Whereas in reality, it really doesn’t matter. This is because the interpretation of the barcode is all up to the protocol standard that it is using. For example with the case of a UPC-A type barcode, where it uses a 7 bit array to denote numbers. Different value bit arrays can symbolise the same (base 10) number depending on it’s location on the barcode.

image of a UPC-A barcode
UPC-A barcode image taken from wikipedia.org
table taken from wikipedia.org
Example of a 1D barcode in use as store’s inventory identifier

Consumer uses for QR Codes

I’ll limit this discussion to consumer use cases and applications because industrial applications are rather dry. They use QR codes in the same way they use other barcodes. Which is to orientate machines that operate with and around physical goods. This could include use cases such as at an Amazon sorting depot, barcodes are used to inform the sorting machines of what goods are in what shelves.

Where as within the consumer space; most QR codes in the wild, are simply used as a means of storing website links and affiliate information. These are designed to allow people to simply scan the code out of a magazine, business card, coupon, or what-have-you; in order to very quickly load the website hyperlink and/or fill a virtual document.

For example, a QR code at a public WIFI access point will have all the data necessary (link to login page, SSID, password) to allow the scanning smartphone to access their network. Likewise a QR code on a coupon will link to the retailer’s online store page and pass any promotional offers associated with that coupon automatically to it’s e-shop.

QR codes, at least when dealing within the consumer space, are predominantly a means of convenience. They reduce the friction encountered when user’s operate within virtual spaces. Friction such as inputting long arbitrary names or numbers (such as a WIFI network’s SSID or password); or website domain names, where a typo could expose the user to a potentially malicious imitator website.

The friction is reduced because the process of scanning a code with a modern smartphone is far easier, than inputting the data manually using (most likely) a touch keyboard into that same smartphone. Another benefit is the probability of user error (such as mistyping a password or domain name) is eliminated. This is done by automating the process of data entry and bypassing the user in that work flow. That’s what I believe constitutes the vast majority of useful applications of QR codes in the consumer space, at least this is the case when talking strictly about static QR codes.

Additionally. The Wikipedia article for QR codes list many different (specific) use cases for them in the the consumer space; however in my opinion they all boil down to the two things I mentioned earlier: following links and filling in virtual documents.

Anatomy of QR codes

The smallest unit of information on a QR code is referred to as a module. A module is a single square that is coloured either white or black. For example a version 1 QR code is made up of a 21 by 21 module grid, totalling 441 individual modules. If you were to count all the chequered squares along either axis, it will add up to 21.

Look at the below two examples, both of these QR codes are identical Version 1 QR codes. They both have the same 441 distinct modules on a 21 x 21 grid. The only difference is the actual image size. This should illustrate that (within reason) the actual pixel (or print) size of the modules doesn’t matter with QR codes. As long as the scanning devices’ cameras can fit the entire code structure within frame and focus.

Bash instructions:

qrencode -o qrc_V1_small.png -s 3 'ECC'
qrencode -o qrc_V1_large.png -s 6 'ECC'

A QR codes’ modules are organised into several structures. These include: three position markers, several alignment markers (number varies with version/size), a version information zone, a format information zone, a timing zone, an area for data and error correction keys, and finally a blank quiet zone to denote the border of a QR code.

image taken from wikipedia.org

QR code size specification

QR codes are rather versatile, they have the ability to encode: ASCII symbols (letters and numbers), media (images, sound, and video), as well as even executable programs (compiled binaries). However, although they technically have this capability, it is severely hampered by the size limitations of the QR code standard.

At the time of writing, the largest viable QR code that can be created is the ‘Version 40’ variant. QR code Version 40 can encode up to: 7089 bytes of pure numerics, 4296 bytes of alphanumerics, 2953 bytes of miscellaneous binary (e.g. media), or 1817 bytes of Japanese Kanji characters. This is done using the lowest value (level L) of error correction, thus leaving more space for actual data. So these are the absolute maximum values.

Refer to file “QRcode_version_table” below for a full list of all version specifications.

image taken from wikipedia.org

Test case of numerical barcode capacity

This was an interesting one, because although the version 40 QR code specification states that I could create a numerical QR code with a capacity of 7089 bytes. In actuality the maximum amount of data that I managed to fit into a QR code was 7080 bytes. I honestly don’t know what to make of that. The ECC (level L) was supposed to be factored into the 7089 max value, i.e that is the maximum data storage in addition to the space that the error correction takes up. So it can’t be what’s limiting me from the max value. As to what is happening, I’m not sure. It could be anything, including a limitation of the program I used to create these codes (qrencode), or it could be some unknown setting, text file associated metadata, or even some unnoticed human error in play. Hence I will include the input files I used here so that you can try it out yourself, and see where I messed up.

Bash instructions:

qrencode -r pi_decimals_7081.txt -o qrc_pi_7081.png
Failed to encode the input data: Input data too large

qrencode -r pi_decimals_7080.txt -o qrc_pi_7080.png
Successfully compiled QR code containing 7080 bytes of pure numbers
According to Xed, this file weighs 7080 bytes.

QR code Error Correction Capability

QR codes have a built in Error Correction Capability (ECC). They use the Reed-soloman error correction codes in order to facilitate a certain level of data redundancy. This enables QR codes to be readable even after they have sustained damage. Such as by getting scratched or being partially obscured by grime. This error correction facility comes in four levels: L, M, Q, and H. The error correction of each level is expressed as a percentage of the total data that can be lost whilst maintaining the QR codes readability.

This is as follows:

  • L has up to a 7% ECC
  • M has up to a 15% ECC
  • Q has up to a 25% ECC
  • H has up to a 30% ECC

Generally speaking, the error correction capability of a QR code isn’t free. The higher levels take up more of the QR code’s finite available space, space that could otherwise be used to encode more of the actual substantive data itself. This trade off between useable storage space and data read reliability, means that QR codes with higher ECC tend to be used in environments where code damage is more likely; or in applications where the printed QR code itself is going to in active operation for a longer time period. Such being attached to warehouse racking to identify the specific shelf location and product contents to an automated sorter machine.

image taken from archive.org – qrcode.com page

How to spot the ECC level on a QR code

To work out what type of ECC level set on a QR code, look towards the “format information” zone to the right of the lower left position marker. Immediately after the single column of blank (white) modules of the position marker, at the bottom of the QR code and the module just above it. These two modules display what level of ECC is employed within the QR code.

Bash instructions:

qrencode -l L -o qrc_ECC_L.png 'ECC'
qrencode -l M -o qrc_ECC_M.png 'ECC'
qrencode -l Q -o qrc_ECC_Q.png 'ECC'
qrencode -l H -o qre_ECC_H.png 'ECC'

zbarimg *.png

Using ECC to incorporate logos into QR codes

When I looked into how people actually created the fancier QR codes; the ones’ that incorporate graphics such as text and logos. I was genuinely surprised at the crudity of the methodology. I thought that it may involve something akin to passing arguments to the QR code generator to re-route the data sectors around the graphic. Nope. It’s actually laughably simple. If you wish to incorporate graphics into your QR code, just crank up the ECC to max. Output the QR code. Then slap that graphic on top the QR code using some graphics manipulation software. In this case GIMP. Done. I mean it does the job. I just don’t like the idea of purposefully damaging data integrity.

Look at the below examples. Both of these QR codes hold the same data. This being a link to this website’s homepage. The size disparity between these two is caused by the additional error correction code added to the level H QR code. It caused it to jump up a couple of versions. I’m guessing that since my logo covers more than 7% of each of the QR codes, this is the reason why the level L QR code is no longer functional, whereas the level H QR code continues to function after the addition of the logo due to the logo covering less than the 30% of it’s maximum error correction capacity. This methodology seems rather crude, but it works.

Example of a real QR code that incorporates a logo

Encoding and decoding QR codes

There are numerous ways to generate your own QR codes. I’ll just mention a few to give you an idea of where to start.

Firstly, I should mention that there are paid services that allow customers to get custom QR codes. This includes things like “dynamic” QR codes, that can supposedly keep a tally of the number of times they have been scanned. However if you aren’t using them for professional applications. I generally wouldn’t recommend using paid services like these. This is a tinkerer’s blog after all. That being said, I mention them here just to make you aware of their existence.

All the tools that I mention from this point are free to use and readily available. If you are using a Linux based operating system, or virtual machine, or use bash in Windows. I recommend downloading and using two programs: “qrencode” and “zbar-tools”. Both are available in the Ubuntu main repository. This is actually what I primarily used to create and test all the codes in this article.

The zbar-tools toolkit comes with two relevant programs. zbarimg and zbarcam. zbarimg is used to scan local images of QR codes and can output that data either to standard output (usually the shell), or piped into a file. zbarcam has similar functionality, except it can use the computer’s camera to capture a QR code.

Alternatively, for quick QR code generation you could use an online website. I don’t want to recommend any for liability reasons, as there are lots of random websites that can do this. What I found interesting though is that the search engine duckduckgo.com actually can generate QR codes as well. I came across it rather by accident, as it returned QR codes with the search term data within it.

To use DDG to create a QR code, just type in “qrcode” followed by a space and then whatever textual data you want in it. I find this method rather novel, and probably good for simple quick and dirty codes. However it lacks the precision of functionality that a program like qrencode gives you. Such as the ability to specify the module size, and ECC level of the generated QR code; qrencode does this by passing arguments to the program.

TLDR

Tools to create QR codes

  • Linux: qrencode
  • websites: duckduckgo.com, etcetera
  • paid services for business including dynamic QR codes

Tools to decode/scan QR codes

  • android phone apps
  • (zbar-tools) zbarimg & zbarwebcam

Encoding and decoding binary QR codes

To encode a file (such as an image) into a QR code, you need to pass an additional option to qrencode. Use the -8 argument to specify 8 bit mode. You also need to use the -r option to specify a file input.

qrencode -8 -r input_image.png -o output_qrcode.png

To decode a QR code image of a binary into a file. You have to pass the below options to zbarimg, to allow it to know that it is dealing with a binary file. Additionally you then need to pass the output from zbarimg into a file. Otherwise it’ll just output the data into standard output (i.e. the shell itself).

zbarimg --raw --oneshot -Sbinary qr_code.png > output_file.png

One thing to note. Versions of zbarimg (zbar-tools) older than version zbar-0.23.1 do not have the capability to decode binary files. Additionally, at the time of writing the version of zbar within the Ubuntu repository was zbar-0.23; an older version without the capacity to decode binaries.

Alternatively decoding a binary QR code without specifying the output format, or without piping the contents into a file; instead just letting it output into the shell: will cast the contents as ASCII text. Instead of a file it will output a string of nonsense characters. However the first couple of legible characters should consist of file metadata that can tell you what format the binary data is in. The below example is the same QR code as above but outputted as ASCII rather than as a binary.

QR-Code:‰PNG

\00\00\00
IHDR\00\00\00Œ\00\00\00Œ\00\00\00!¢Öi\00\00IDATxÚíݱmƒ@†á8rÏ\00´i#s¤af`7™Ã‹¸e\006Hé”|`r<oé\ù^}÷c[>õ}ÿ‚}ójHBÎNJ¢Xã?5M“ÙÞµm»øwÿt•‘$u‡´uZîýíclõõö9»f–ªª2ÛÄ»v;¦÷$IÝa¥Óݑ©ëzvÍårIؐ1½'Iêê.§“áDïI’ºƒº;HïI’ºI$$DHI$$’@H"	$$’@H"	$oéúE’7ãK’ºCuÞe>—ϵÍmïùLª$©;ü—ÓÝfI‡$‘’HI ‰$’HIG%Ù+³^¼ÈžTw8%IÝauZ®ë:»yGY–IzO’ÔH"	$aûa6œd I$!ïº3Ì®w	$u’HI0ÌJH‚aÖ0uGHINw†YIIêÎ0k˜I$$’`˜…$‘ìaV’ÔH"	$Á0+I 	†YÃ,ÔH"	$‘’@I 	$‘„58ö™OßýÞ/[¿ÁeI’¤gh:Ã5cëcþš$Iâ®aO“4ñåb©¾cëh,ÛRIzô¶AÂ\“³ Éé.[¾¯.ñw¦×ÿüéJӒ$IÒîó”j½;’4Ž‰59˶T’Á‘‚Sß÷wEa_žÈЈ$©;¬Tw$”#_{G}¨õ—´\00\00\00\00IEND®B`‚

Closing thoughts

QR codes are basically ubiquitous today. They are present everywhere. And applicable in many use cases ranging from anything; from storing simple web links, to gaming uses such as markers for augmented reality. I recently found a tiny one that was printed into the underside of my kettle. Why is it there? Just because. The point is that they are everywhere.

Additionally, the technology is exceptionally accessible. Having a surprisingly small learning curve. This coupled with the fact that quality creation tools (like qrencode) are freely available, means that if you for whatever reason would like to use a QR code within your work; there is little reason not to do so.

If I am perfectly honest however. I personally don’t see much actual utility for me other than inserting a QR code linking to my website, or email within a business card. Perhaps, even in printed articles – as a means of linking in additional online resources. It’ll certainly have a lower level of friction, than printed hyperlinks have.

If I’m honest. The main real appeal of this technology to me is the novelty of storing binary information within a printable medium. The fact that you can encode an actual binary (so long as it is smaller than 2.9kb) into a paper medium, is wondrous. Check the links below for a Youtube video of a person who encoded an entire executable game into a static QR code. Not a web link to game. The game itself. Imagine storing actual games, into a book. Tiny games, but still. Cool.

Anyway, happy QR coding. Thank you for reading.

Some fun

Links, references, and further reading

https://www.youtube.com/watch?v=ExwqNreocpg

Scan Barcode QR Code From Webcam & Image File in Linux

The purpose of QR Codes

QR Codes basics

https://en.wikipedia.org/wiki/QR_code#storage

https://en.wikipedia.org/wiki/Binary_number

http://qrcode.meetheed.com/question14.php?s=s

https://www.linux-magazine.com/Online/Features/Generating-QR-Codes-in-Linux

https://www.binaryhexconverter.com/ascii-text-to-binary-converter

https://en.wikipedia.org/wiki/EAN-8

https://en.wikipedia.org/wiki/Universal_Product_Code#Check_digit_calculation

https://en.wikipedia.org/wiki/Barcode#Symbologies

https://en.wikipedia.org/wiki/Binary_number

How To Convert Images Into ASCII Format In Linux

http://www.qrcode.com/

https://web.archive.org/web/20130127052927/

http://www.qrcode.com/en/qrgene2.html

https://www.thonky.com/qr-code-tutorial/error-correction-table

https://scanova.io/blog/blog/2018/07/26/qr-code-error-correction/

https://www.qrcode-tiger.com/qr-code-error-correctionhttps://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction

https://medium.com/@r00__/decoding-a-broken-qr-code-39fc3473a034