On 25 March 2020 New Zealand went into Level 4 lockdown. The New Zealand Government sought a digital solution that would enable New Zealanders (once back out in the community) to privately track the places they had visited, and get notified if they had been in close contact with someone with Covid-19.
There were two parts to the solution: Tracking poster & Mobile scanning app/notification system.
Aaron Yee (Transition Digital) was the technical lead of the tracking poster. This article does a deep dive into the constraints, analysis and decisions made for deploying a barcode into the public domain that was successfully scanned 804 million times.
This poster/barcode was formed within the following constraints and considerations:
Analysis was done by looking at three different barcode types:
GS1 Datamatrix - The GS1 Datamatrix did not support special characters such as ā, ē, ī, ō, ū from the Māori language. A later decision to encode the data with base64 would have avoided the technical need for the barcode to support this. However this also neglected one of GS1's biggest selling points that their codes were "human readable"
QR Code - Supported Macrons and special characters, for example "ō", required around the same data storage space as having two o's eg: "oo". This was a non-material difference and was considered when deciding on the QR code version.
As a goal was to maximise privacy for New Zealand citizens, the barcode was required to contain all the check-in data (like someone writing down where they were in a private notebook). Upon scanning, mobile phones would simply log the data in the mobile app instead of being required to do any secondary API lookup.
A JSON schema was used as it offered maximum flexibility for both the poster generation team and the mobile app development team to easily use modern libraries to encode, decode and use the required data.
{
"gln": "9420000000000",
"ver": "c19:1",
"typ": "entry",
"opn": "Business Name",
"adr": "Street Number\nStreet Name\nCity"
}
For data integrity reasons the JSON key-value pair was encrypted as base64.
NZCOVIDTRACER:eyJnbG4iOiI5NDAwMDAwMDAwMDAiLCJ2ZXIiOiJjMTk6MSIsInR5cCI6ImVudHJ5Iiwib3BuIjoiS2Fpa8WNdXJhIEJha2VyeSIsImFkciI6IjE2IFN0cmVldCBOYW1lXG5Sb2FkIE5hbWVcbkNpdHkgTmFtZSJ9
GS1 Datamatrix - Under the GS1 Datamatrix the data must be structured according to the rules of the GS1 System. These can be found in GS1's 501 page GS1 general specifications document. For example:
(01)
03453120000011
(17)
191125
(10)
ABCD1234
The way the data format works is that (01) (17) (10) represent identifiers from the GS1 index table. This makes the code "human readable" where humans would know or be able to refer to the index:
(01) = a 14 digit GTN
(17) = an expiration date of 25 Nov. 2019
(10) = Batch Number
A couple of challenges with the GS1 datamatrix option:
QR Code - There was no specific standard to follow, meaning it was possible to inject the the base64 JSON schema into the QR code without any issues. Within hours the team at the Ministry of Health who were developing the mobile application were able to generate a website to test the reading of the code and present the encoded data. Support for QR decoding is also offered natively within Webapps, Apple and Android libraries for QR code reading.
Error correction inside barcodes allows for the code to still be scannable, even if there are issues with the code. For example poor printing, light reflection at time of scanning or being damaged from water/folding/tearing. All of these could be entirely possible as codes would be deployed throughout New Zealand so error correction was of vital importance.
Both the GS1 Datamatrix and QR code generation follow the Reed-Solomon Code for data correction and dynamically range from approximately 7% to 30% of correction.
QR Code: Testing undertaken showed that the QR code version could be specified, which in theory would allow a higher percentage of data correction to be generated into the code. More on QR code versions can be found here.
QR code was the most supported native barcode reader that would be compatible with the oldest mobile devices. This paired with forcing a high Error Correction (ECC) means we could include almost all New Zealanders that had a mobile device.
Some consideration went into analysing if businesses had multiple codes close to each other, then the scanner may process the incorrect code or the possibility for malicious codes to navigate users to bad websites. In real life every New Zealander was told to download the app and to scan the code within the app. This meant that if the code contained anything other than the defined format of NZCOVIDTRACER, it would come up with a message that says invalid code and a citizen could move closer to the poster and try again.
As a result of the findings above the decision was made to go with the QR code as the barcode of choice for the NZ COVID tracer poster. The next step was to decide on the QR code version and do some preliminary testing.
To work out which QR code version to use, an analysis was performed regarding the potential minimum (116 characters) and maximum (282 characters) data requirements that needed to be stored inside the code.
This gave a theoretical range of 116-282 alphanumeric characters and one ":" character.
Some future-proofing was added into the code just in case additional parameters needed to be introduced at a later date. This was called the "Stretch Max" with a length of 330 characters.
At first when looking at the type of data that needed to be encoded, it was thought that the below base64 data string was mostly alphanumeric.
NZCOVIDTRACER:ewoJImdsbiI6ICI5NDI5MDQxMTk4Nzk3IiwKCSJ2ZXIiOiAiYzE5OjEiLAoJInR5cCI6ICJlbnRyeSIsCgkib3BuIjogIlRoZSBXYXJlaG91c2UgR3JvdXAg4oCTIFdlbGxpbmd0b24gQ2kiLAoJImFkciI6ICIxNjIgVGF1bWF0YXdoYWthdGFuZ2loYW5nYWtvYXVhIHVvdGFtYXRlYXR1cmlwdWtha2FwaWtpbWF1bmdhaG9yb251a3Vwb2thaXdoZW51YWtpdGFuYXRhaHUiCn0=
So using a look-up tables with a stretch max of 330 characters it was assumed that the best version number was going to be version 11.
However...
When attempting to generate the stretch max code at this version number there were issues.
Turns out Alphanumeric characters are limited to the following:
1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ
, a space character “ “ and other letters $%*+-./:
The data requirements included lowercase characters which means binary mode must be used for any lowercase letters. Based on this, the data table was consulted once again.
Version 13 looked to be the new best version number to use.
There are so many different ways to generate QR codes. A massive amount of online APIs including Google QR code generator. The thought was that it was best not to be reliant on the availability of these 3rd party services.
It was decided that the open-source library bwip-js created by Metafloor was the best option. The advantages were:
The Ministry of Health undertook robust testing of the posters but some preliminary testing was carried out prior to this.
The printer was running low on toner.. Pasted on the fridge using Aaron's parents as guinea pigs, they were able to successfully "check in" to their fridge.
There was a considerable amount of thinking that went into choosing the barcode type for the NZ COVID tracer poster and ensuring its robustness when deployed into the wild.
If you're navigating the complexities of QR code technology for your project, consider reaching out to Aaron or the team at transition.co.nz.