Mechanical sympathy for QR codes: making NSW check-in better
huonw.github.io
huonw.github.io
And when the code won't scan, people's natural tendency is to then move closer to the QR code (make it fill the whole screen), which doesn't help at all. But if they instead initially move away it can fix the issue.
I'm not sure what would cause this? Maybe a reduction in relative angular distortion? Or perhaps only a crop of the image is "scanned" for QR codes?
But yeah this, (very) anecdotal, data point would counterintuitively push for a smaller QR code than "Works now"(maybe 10-20%).
The best experience I have had was the Queensland system. The QR codes I saw were different than explained at the end of this article. They were small (Original NSW size) but very simple codes. From the look and the number below, I assumed it was just a 6 digit number. Those would scan very fast (as in while I was still moving the phone at speed to align with the QR code).
In NZ the behaviour is: stop, aim, scan, wait, done. But in Queensland it worked so well I could just keep walking, wave my phone in the direction of the barcode and it would catch it.
Anyway, I just found those experiences very interesting, maybe others will too :)
003|eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZiIsImVucCI6Imh0dHBzOi8vd3NzLmNvb3YuaW8vMDEyMzQ1Njc4OUFiQ2RFZkdoSWoiLCJpc3MiOiJBQ01FIiwiZXhwIjoxNjAwMDAwMDAwLCJ2ZXJzaW9uIjoiMDAzIn0.AEwfg3OC34g07x_xVWekdUumxPTqbrRFvQkOVV_TQT4
That got encoded into a fairly large QR code---61 by 61 modules (version 11, error correction level L)---and it is always painful to get it recognized, mainly because every merchant's device is different and some devices and/or apps are particularly less responsive.It is very noticable that there is a lot of redundancy here: the format of JWT payload will be very regular, always having `sub`, `enp`, `iss`, `exp` and `version` (fixed to `003`) fields in a verbose base64 format for example. It makes a fun challenge to optimize this into something much smaller.
It's something that stores post on all their entrances so that visitors can record their visit in the appropriate check-in application.
The merchant has no access to the data, it's sent to a state government datastore. (Although questions over it's security still remain).
It's also supposed to be able to operate in offline mode - where cellular and wifi signals are unavailable. For instance, a shopping centre's entrance in the middle of an underground carpark.
I'm sure offline check-in was mentioned at some point, but then promptly dismissed, likely by a product manager saying "they can just check in using pen and paper".
As for outages, even as a (paying) commercial customer, the closest you'll get to an SLA from any government agency is: "apart from scheduled maintenance and subject to unexpected outages, the service should be available 24x7"
I haven't read the submission, so the subject of "this" is unclear. Are you referring to Vietnam, South Korea or Australia?
The base64 encoding in JWT's forces the QR-code to use segments in byte-mode. This will encode individual JWT characters in 8 bits of data.
The size of the characterset of a base64-encoded JWT is 65 (64-characters in base64 + '.'). Actually, in this spec, it is 66, including the `|`.
An optimal encoding would use Log2(66) amount of bits per character. Alphanumeric mode at 5.5 bits per character is too small, but encoding individual JWT chars as 2 numeric characters (at 3 1/3 bits each) results in a more optimal encoding (~20% space savings).
The mapping from the JWT char to 2 numeric coding is also quite trivial: take the ascii value of the char and subtract by 43. ``` def enc(c): return "%02d"%(ord(c) - 43) ```
The fantastic website https://www.nayuki.io/page/creating-a-qr-code-step-by-step
shows, for the JWT you posted, a size of 2164 bits needed to encode the data inside the QR-code at low error-correction (resulting in a version 10 QR-code).
If we run every char through the numeric encoding process, we get the following result: ``` 05050881587831055845226236623132430638623324316155285662366231304279300635623114035878317957443062366230763441307935254207357960104644316347284366342526783479380635635609364427624607396547623072306643745624301130666105572923793662137557083579336635755508467454441375342526783479380635635609364227623807392747645768404468623324316956083462366231233805062730627662474561763063687735632276342522763425227633243107474531795444147430636862342522793067050322267659600836240809600512775277434458645742746677374170557139277538643643435241384109```
Longer in terms of characters, but if we run it through the QR-encoder, we get a bitstream of length 1801. Which is possible to fit in a Version 9 (err corr L) QR-code.
I thought this was pretty cool :)
NZ Covid Tracer App is actually open source and the QR code reading function can be seen here: https://github.com/minhealthnz/nzcovidtracer-app/blob/main/s...
And here's the type for the JSON we use: https://github.com/minhealthnz/nzcovidtracer-app/blob/main/s...
Typical example of a QR code can be found here: https://lenny.cf/all-qr-codes
And interesting. It seems like the trade-offs are slightly different, although, unless I’m missing something, using URLs does work slightly nicer for people without the appropriate app installed (or scanning with the built-in camera app or other scanner).
HTTPS://S.NSW.GOV.AU/C/121321/Test+NSW+Government+QR+code (binary mode)
HTTPS://S.NSW.GOV.AU/C/121321/TEST+NSW+GOVERNMENT+QR+CODE (alphanumeric mode)
He ruled out full alphanumeric mode early on, prior to ditching Base64, but it's sensible to reconsider it by the time you reduce the URL this far. He goes on to allude to simplifying or even dropping the business names to save more space at the cost of lost functionality, but just uppercasing them seems benign to me.
It's a nice write-up all the same.
That’s true, the business name could be uppercase, but it feels suboptimal to be changing text displayed to users (and shouting at them). It would drop the final version from 5 to 4.
I can't wait to see how dreadful the vaccination passport apps will be. With the current "digital certificate" being a pdf with zero security, it is sure to be laughable.
With cases now in the hundreds/thousands per day in Australia, plus widespread vaccinations, these QR codes are pointless... same as masks and international border restrictions.
I checked my history the other day and noticed some businesses missing so there probably are some bugs in the process.
Thanks!
Many places I've seen have taken a 'defence in depth' approach, where they put up numerous copies throughout their entryway so that multiple sets of people can check in simultaneously. Either on top of the pylons holding barrier ropes, or against multiple doors in an antechamber, etc. That also works well for getting people through.
https://www.reddit.com/r/sydney/comments/pp0kpg/why_are_the_...
I have no issues with my phone (until yesterday when I encountered some creased laminate), but it's new. The most obvious improvement to me is what the article pointed out - use more of the paper you're printing on! Make it bigger. Worst case, we all get to stand back a little.
And yeah, the biggest win is definitely just making the code itself larger.
For these particular posters, I suspect they’re generated in HTML/JS that the business can then print in their browser (or generated directly as a PDF, but I’ve seen some posters that have the classic printed-from-web-page header and footer with URL etc).
There’s a lot of businesses in NSW/Australia, and all the posters are near identical. Thus, they wouldn’t be hand-crafted each time, and programmatically inserting a custom code into a word document would be a … surprising implementation decision (to me).
On the scheme, I'm not sure `https` is needed, at least when scanning with the iphone camera. Parsing seems to be based on the TLD and potentially subdomains, e.g., `example.com` will parse as an address but lesser-known ccTLDs like `example.ws` will be parsed as text, which is interesting.
Ideally, one would set up SSL redirection, so dropping the `s` from `https` wouldn't be a sec issue, and have a naked domain so that the `www` CNAME isn't needed either. Checking their website, that seems to be the case, so they could potentially drop `https://www.` from the QR code
$ curl -IL http://service.nsw.gov.au/
HTTP/1.1 301 Moved Permanently
Server: awselb/2.0
Date: Wed, 13 Oct 2021 00:34:35 GMT
Content-Type: text/html
Content-Length: 134
Connection: keep-alive
Location: https://service.nsw.gov.au:443/
HTTP/2 301
server: awselb/2.0
date: Wed, 13 Oct 2021 00:34:35 GMT
content-type: text/html
content-length: 134
location: https://www.service.nsw.gov.au:443/
(explicitly with `http` but it redirects properly without any protocol)_If_ you can rely on the domain being in the HSTS preload list, and if you assume the browser knows that and cares, then it's probably fine.
Otherwise though, the data in the URL will be sent in the clear, and also you can be silently redirected to any other domain/URL if someone can MITM you (which in this case could be pretty trivial just by some variation on setting up public wifi).
Not entirely clear to me if any of that matters for this particular use-case. I can't think of an actual attack that's not available by just making a malicious QR code instead. It still feels a bit ick though.
For instance, scanning with an iPhone camera will jump into the browser, rather than to the app (example, you have two devices handy: https://duckduckgo.com/?q=qr+code+https%3A%2F%2Fservice.nsw.... )
The main problem with fast scanning is selecting one at the right height. Often the first I encounter is placed at waist level for wheelchair access which is a very good thing but often worth walking past that and using one at a better height for me as the keystoning of the image makes scanning less reliable.
The checkin data in my state is guaranteed to be kept for 28 days and treated as health data and not available for other purposes. But it was recently announced they discovered they had been keeping backups for longer than 28 days by mistake. That is probably quite relevant to a lot of businesses I think. Backups tend to be handled separately. I am sure I have worked on many systems where client data has been deleted in the app but persisted in backups long after they should have. Might be some lessons in that.
You can create forms for variables that get injected/interpolated into barcodes/images.
I just added the ability to print from the command-line or via URL. I’m looking for label printing system integrators and offering free licenses if you mention you found my app on HN.
I’d love to work with people on issues like this. Cheers!
Download from https://label.live
My app, when possible, talks directly to the printer via USB at a low level, which means all page-size/speed/darkness/DPI/features of the printer can be controlled outside of what the operating system driver exposes. Each of your label designs can have their own print settings without having to tinker inside printing menus.
Lastly, the app’s saved design files can be opened on both Mac and windows without worrying that the printing experience will be different.
However, the way the codes are used in Victoria is different, which means the size of the QR code doesn't matter much. (They tend to be about 1/4 of an A4 sheet, so larger than in NSW.) No-one is checking your phone to ensure you checked in; rather, it's an honesty system. So the codes are generally in the window near the door, and you stand off to one side. In those circumstances, if the code were larger and you could stand farther away, it would actually be less safe because it might encourage more than one at a time to use the code. As it is, a queue forms with polite distancing, like an ATM. (Remember those, and cash?)
We also have QR codes at every tram and bus stop in Victoria, as laminated A4, so they definitely do need to work outside. I haven't used those, but ones in shop windows work fine when it's raining. The only problem I ever encountered was a QR code on a bendy laminated piece of A4 indoors, under coloured lighting.
Vaccination status is integrated with the Victorian app, because it was that state that was tasked to work with the Federal government to implement and (together with the NT and Tasmania) test that. It is currently undergoing testing in rural Victoria, although anyone in the state can load their Federally-issued vaccination certificate into the app. NSW have not yet taken the code and put it in their app, probably because the people doing that expected the restrictions to be eased on the original timetable.
While loading the certificate into the apps should be technically simple, it isn't, because of 1980s Federal laws to do with sharing of medical data. (They know my phone number, Victoria knows it, but it is against the law to match it. I must log in to the Federal site or the Federal app on my phone and authorise it to copy the certificate into the state app, and I must keep doing it every few months.)
That said, it seems like there’s two versions of the Victorian codes. I can find others online that have a base64 snippet containing:
{
"t":1,
"lid":"<base64'd 64-byte ID>",
"ln":"<name here>
(Yes, seemingly without the trailing "}, as a microoptimisation?)This uses error correction M, and ends up as a version 12 code.
I don't know for sure which codes are 'current' but I suspect the JWT ones are the older ones, based on https://www.theage.com.au/national/victoria/victoria-s-qr-co...
I suspect having larger codes makes a big difference to the experience. It does seem like the Victorian ones are more like 15% of the page area, rather than 5% for NSW.
Vaccination status and so on is a whole other can of worms beyond how the QR codes work and could be better.
In contrast, in Quebec Canada, the QR codes are issued to people once they get vaccinated, and contain the person's name and vaccination(s) statuses, and digital signature by the issuer directly in the QR code.
The government then published 2 apps on the app stores: * App for users to easily host the QR code (instead of email/PDFs/etc), but more importantly: * App for businesses to scan the user-presented QR code and validate the signature, to allow into the premises (after also checking a photo ID to ensure person face matches ID and ID name matches name in QR code)
The above is because some businesses, like sit-down restaurants (even if eating on the terrace), are required to ensure patrons are fully vaccinated.
I don't know if the "scan" app also remembers who it scans for contact-tracing purposes or not - but there's a separate contact-tracing app for that, also published by the government, that uses iOS's and Android's contact-tracing facilities.
They could do so much more with the check ins. We had a rule that one household member could leave once per day for essential shopping. It would be trivial to get people in trouble based on known addresses and check in history, same for the 5km rule. But they clearly don't want to antagonise the populace too much.
It's more likely because the government realises that if they started fining people for correctly checking in, but going to the shops twice in a day, is likely to result in them just not checking in at all.
Also, the app doesn't require users to actually verify your name or phone number, so you could just put anyone's details in and they'd start copping fines for your misbehaviour.