Hacker News new | past | comments | ask | show | jobs | submit login
Mechanical sympathy for QR codes: making NSW check-in better (huonw.github.io)
134 points by dbaupp on Oct 12, 2021 | hide | past | favorite | 64 comments



Something that I have found very interesting: In New Zealand the QR codes are like the "Works Now" NSW ones. The combination of the A4 page size, the QR code taking up most of that page and peoples natural standing distance away from the posters, roughly means that the QR code takes up most of their screen. And I am not sure why, but some phones seem to really struggle with this setup.

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 :)


From my experience, the problem is the lamination of the NZ ones, causing refraction and making it hard to scan. I find that even at the right distance I have to move my phone left and right until the light isn't reflecting


The QLD ones suffer the same issue. I imagine not as bad. But anecdotally the plain paper codes scan as fast as you want. The laminated ones you have to move the camera about to make sure there is no glare interfering with the image


In SA the codes are fairly small and scan very fast from a distance. Even if they are laminated and placed behind a window they scan easily. Meanwhile the gigantic QR code printed on a 7 foot poster which was used for express check-in at the Wayville showgrounds vaccination hub just did not work on my phone.


For the geographically illiterate, NSW refers to the Australian state of New South Wales (vs. Not Safe for Work, Naval Strike Wing, Newman–Shanks–Williams prime number, Nintendo Switch, or U.S. Naval Special Warfare Command).


The workflow is generally reversed in South Korea: the visitor shows a generated QR code to the merchant's camera for the check-in. (There are also multiple fallbacks available.) The QR code is, to my knowledge, a very short living JWT credential and looks like this: (I've redacted pretty much every nonce for the obvious reason)

    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.


To be clear, this is not merchant-customer relationship for payment, or for any interaction at all.

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.


Important to note that offline mode (for QLD at least), was only introduced a few weeks ago, and only after a major service outage. QLD went almost the entire pandemic without something I would have thought was a critical feature (I am sure that I am not the only person walking around with a smartphone without a mobile data plan).


Given my experience with government IT, none of that surprises me at all.

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"


>To be clear, this

I haven't read the submission, so the subject of "this" is unclear. Are you referring to Vietnam, South Korea or Australia?


"This" appears to be about Australia, as that's how things work here in NSW


Ah, that makes sense. In fact I was not sure why replies try to say about the offline usability of certificates as I just used a SK approach as another example of inefficient QR code uses. I don't think the SK approach is better than others or vice versa as long as proper fallbacks are provided and it seems it's the case for either NSW, SK or EU anyway.


Just thought this would be interesting to share.

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 :)


The EU vaccination certificate (which is shown as a QR code in e.g. restaurants or public events) is twice longer than your example (572 characters for me), but it includes all the data and a digital signature to allow offline verification of whether that certificate is valid.


Really interesting write-up! New Zealand COVID Tracer app QR codes are actually pretty similar. We don't use URLs, but we do use a base64 encoded JSON prefixed with the "NZCOVIDTRACER" string.

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


Thank you!

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).


Yeah that's a trade off we have - without the app installed scanning the QR code yields "No usable data found".


That must depend on the app, because it should be possible to view the raw prefix+base64 encoded character data, at least.


I think he could have saved even more space in his final pass by uppercasing the business names:

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.


Thanks!

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 wouldn't even argue this is a loss of functionality- it's rather standard for data (especially when working with government systems, at least in the US) to be presented in all caps.


The way the govt did these codes was ridiculous. Many retailers put them behind a glossy protective plastic, and they are so hard to scan and really slow things down unnecessarily. I guess they were rolled out quickly or by someone inexperienced with QR codes.


Some retailers go worse, they had someone screenshot the QR code, then printed out a bunch of them at half-size so they could plaster them all over the place (at every table). But because they resized them using some dithering pattern, they start out slightly blurred. It gets worse when they're exposed to moisture (they're sticky-taped to the tables/counters) as the ink then bleeds. Scanning this is a pain.


I’d guess it was probably a combination of a quick roll-out, and also concern that people wouldn’t know what to do with them hence a lot of the text is emphasised. (I could also imagine there was mostly testing in “laboratory” conditions, scanning codes displayed on screens, but hard to say.)


I find that the codes will in fact scan if you use a third party QR app. Luckily, the URL will open directly to the Service NSW app's sign in page, so whoever was in charge of that got something right.

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.


I've never really had any issues with scanning the QR code


The QR codes are security theatre: https://en.wikipedia.org/wiki/Security_theater

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.


The craziest part is, the QR codes have all the data to be able to work offline. But the app requires an internet connection!


A synchronous online connection. The app stutters and generally hangs/freezes if you have poor connection, which is precisely what happens in most shopping centres.


Uh, huh, I clearly didn’t test it properly. I had thought I’d validated checking in while offline. Oops: https://github.com/huonw/huonw.github.io/commit/fd19b9d66af7...

Thanks!


Why is that crazy? The point is tracking movements, how would that be possible if the government can’t see your location?


They don't need to know where you are, they just need to know when you checked in/out along with a business identifier. Syncing the data later when you're back online would do this fine.

I checked my history the other day and noticed some businesses missing so there probably are some bugs in the process.


I had surgery a couple of months ago and the hospital entry here in QLD had their QR checkin code printed on a novelty-cheque-sized piece of cardboard sitting on an artist's easel outside the entry to the hospital foyer. I could scan it from like 10 metres away without any zoom. It was fantastic.

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.


I find the biggest issue is if the QR code is laminated or not. My phone catches glare and takes ages to scan, but on crappy paper (similar to a sticker on a box in a warehouse) it works great.


Somewhat related, there was a thread that raised the issue on Reddit a little while ago. Mostly anecdotes/complaints, but some technical discussions too (with varying levels of accuracy).

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.


Hah, the discussion and proposals there are remarkably similar. I hadn’t seen until you linked it!

And yeah, the biggest win is definitely just making the code itself larger.


I actually visited Ikea this afternoon and noticed they had the regular ones, but also one they blew up on A3 basically filling the page. Sensible Swedes.


I feel obligated to give a shout-out to the qrcode LaTeX package at https://ctan.org/pkg/qrcode, written in pure LaTeX. Makes creating documents and templates with QR codes a breeze. Though, I'm sure most such printed documents are drafted using MS Word. :(


Nice! Having documents programmatically generating the codes from the underlying data is definitely much nicer and more editable than hard-coding static images (I say this even after writing the blog post that does ridiculous things with SVGs in order to avoid JS, ah well).

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).


Since most government software is written in Java, the QR codes on PDF check-in posters are probably being generated with ZXing [1].

[1] https://github.com/zxing/zxing


Nice writeup!

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)


In general, using http for the scheme has security implications though, even if it gets redirected almost immediately to https.

_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 sure, not something I'd feel comfortable deploying either. The `www` subdomain can certainly be removed at least, I'm fairly certain. Though I would definitely err on the side of caution rolling something like this out since it'd be scanned by all sorts of devices in many different environments.


Unfortunately removing the www doesn't work with the current app. At least for the iOS app, I imagine that www.service.nsw.gov.au is an associated domain, but service.nsw.gov.au is not https://developer.apple.com/documentation/Xcode/supporting-a... .

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.... )


I can mostly scan the South Australian ones on the move and as the article says they appear to be simpler.

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.


The brand guidelines for my three sided cards say version 2 and at least an inch on the side. These scan great. If you can tolerate a db lookup in the server version 2 is all you need.


Related: Most people don't realise that they can use the optical zoom on their phone to stand 2x or 3x further away.


Quick ASCII-2-ASCII compression saved about 3-5% of the examples, so there is even more room for optimization with dictionary-based compression. Trading the app size for more efficiency is justified in this case, I guess.


You can get at least down to 88% in the common case, since there's an unused bit in almost all characters (7 bit ASCII in 8 bit bytes). To actually realise this in practice, one would have to use an encoding that works with the Alphanumeric or Numeric QR modes. (And yeah, dictionary compression would be great on this: lots of repeated text like "Pty Ltd" and "Cafe".)


Indie dev here. I made an electron app to generate and print barcoded labels/images. It’s one of the only apps available allowing windows and macOS users to print to thermal printers without drivers.

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


I have a Dymo driver that I connect via USB, and have never installed a driver.


Maybe not explicitly but the system did that for you implicitly. That’s an entire tangent of pain.

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.


The article says the QR check-in in the neighbouring state of Victoria works offline, but it didn't for me a couple of months ago when I lost 4G signal. Perhaps it's been changed since then – one would hope so, given the existence of mobile blackspots in rural Victoria.

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.)


The Victorian ones are way worse, they contain a massive JWT blob, with a 512 byte signature, really difficult to scan on a lot of phones.


Yeah, the JWT is huge, and contains a bunch of unnecessary data, even ignoring the huge signature (132 bytes, I think?). It even uses error correction M, down from NSW’s H or the article’s Q. It looks like they still end up as version 18 despite that.

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...


(For offline check-ins, that was my mistake even for NSW: https://news.ycombinator.com/item?id=28846384 )

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.


This is awesome. Thanks for sharing!


This is pretty cool, from a "check-in-self-serve-here" perspective.

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.


Here we get a PDF for our vaccination status. Easily faked of course, but they only really started checking them after we "reopened" 2 days ago when we hit the required vaccination rate for gyms, bars, etc.


It's being done differently in Victoria. We can link our vaccination certificate to the Services Vic app and it's displayed as a QR code when we check in.


Dictatorships tend to be more efficient at getting things done ;)

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.


> 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.


I can’t believe people here actually want to help Australia make their surveillance system work better. I wonder why so many people resent tech workers..


Even better solution, stop tracking your citizens.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: