Sjors / nado-book

Bitcoin: A Work in Progress (book source code)
https://btcwip.com
Other
66 stars 14 forks source link

Improve QR encoding and add https:// prefix #42

Closed Sjors closed 2 years ago

Sjors commented 2 years ago

As pointed out on Twitter, the current mini QR codes skip https:// which is not standard compliant and trips up some scanner software. During "field tests" I've noticed Android phones had more difficulty than iPhones, which I initially thought was due to camera quality, but it might be related to this instead.

It's possible to generate a 21x21 QR code, as you can see for yourself on https://www.qrstuff.com, but I don't know how they do that. E.g. HTTPS://BTCWIP.COM/3B:

Schermafbeelding 2022-05-16 om 19 43 16

The mini QR's in the book are generated with the Latex package qrcode. This package hasn't been updated in 7 years, and it doesn't have a lot of config options. It turns out this is not rendering the smallest possible QR code.

An alternative approach could be the pst-barcode package. I haven't tried this because it also requires swithcing from pdflatex to XeTeX which currently triggers obscure errors.

It's also possible to use qrencode to generate the QR codes as images and then include those. Unfortunately I can't get qrencode (version 4.1.1 on macOS) to produce 21x21 QR codes either, without dropping the http(s) prefix, not even with the -8 flag. It always produces as 25x25 QR. This is even true when using all uppercase.

An additional caveat is that my YOURLS instance is configured to be case sensitive, which wasn't a smart choice in retrospect, because case-insensitive QR codes can be smaller. This can probably be fixed in a backward-compatible way though.

The cop-out solution is to just accept 25x25 QR codes and hope the slightly more dense print doesn't matter too much.

Before:

Schermafbeelding 2022-05-16 om 19 55 30

After:

Schermafbeelding 2022-05-16 om 19 59 27
Sjors commented 2 years ago

@stepansnigirev you know a thing or two about QR codes from Specter...

Sjors commented 2 years ago

Some progress:

There's also a Python library python-qrcode. Doesn't seem to perform better than qrencode, but it seems more actively maintained.

orent commented 2 years ago

pip install qrcode pillow

qr --error-correction=L --output=qr.png “HTTPS://BTCWIP.COM/XY

Sjors commented 2 years ago

@orent that works, but it drops the error correction level from M to L. That might be acceptable though. I can even keep mixed case at level L. But QRStuff.com is able to give me level M (with uppercase).

orent commented 2 years ago

The Reed-Solomon error correction is designed for dirt, scratches and situations where a piece of the code is actually missing. I guess you are familiar with the codes that have an embedded logo. They rely on the error correction. For your application a smaller code (i.e. bigger pixels) will help improve readability more than error correction.

Sjors commented 2 years ago

I ended up using the pst-barcode Latex package in c62da9b4ad3ecc0df36db36ed279b7b4813f0c67. This does a better job at making a compact QR code than the qrcode package. At the same time it's easier than generating QR images with a standalone tool like qrencode and python-qrcode and then loading the images.

The only downside is that pst-barcode is not as good at making a compact code as the other tools. So I ended up dropping from https to http. That's still a strict improvement over not having a prefix at all, and I also submitted the domain to the HSTS preload list (which ensures browsers refuse to make an http connection).

PMK commented 2 years ago

On my iPhone 7 it is impossible to scan the QR codes from the printed book. However, when using the Camera app and 2x zoomed in, it does work. Perhaps this also resolves this issue a bit by adding a sentence (Overview > Reading Hints) to zoom in into the QR with your phone if the camera doesn't recognize the QR code?

Sjors commented 2 years ago

@PMK thanks for the feedback! What version of iOs are you on? (iPhone 7 supports iOs 15, but not everyone upgrades)

Did you try outdoors with daylight? Indoors with daylight? Indoors with bright light? Indoors with reading light?

It's the iPhone 7, not the Plus version, right? Because in that case the zoom is pure software (so it shouldn't matter in theory...).

I could probably write several pages on how to best scan QR codes on different devices :-) Sometimes it also helps to hold the camera further away, which isn't intuitive.

PMK commented 2 years ago

iPhone 7 on iOS 15.4.1 (latest)

1-no-qr-detection-with-focus-canvas.jpg This is zoomed out in indoors daylight. It cannot detect the QR code. Note: the yellow canvas is where I tapped on the screen to put the focus on.

. 2-qr-daylight-detection-with-hdr-not-able-to-read.jpg This is also zoomed out and indoors daylight. However, turning HDR on, it does detect the QR code but cannot read it.

. 3-qr-daylight-zoomed-in.jpg This is again indoors daylight, but (digital) zoomed in (2x), no HDR, and it works.

I guess for newer hardware versions of the iPhone this will be less of a problem. Plus, budget phones will have more issues because of a low mega pixel camera spec.

I thought adding a sentence like this: "If you have issues scanning the QR code, for example if you're using an older mobile phone, then try to (digital) zoom in."

Sjors commented 2 years ago

I don't know if the digital zoom workaround is going to work for all phones though. But it might a good tip for iPhone if more people can reproduce this.

The tap to focus feature doesn't always work well; on the first photo it seems that the real focus is several lines above it.