return to table of content

Reading QR codes without a computer

Aachen
12 replies
7h37m

I tried reading them manually about ten years ago, but gave up because of the mask. The mask pattern needs to be applied (xor) before you can even tell as much as the data type...

Does anyone know how much it actually helps QR code readers to have this mask pattern applied?

Last month, I tried to find out what the optimal error correction setting is (answer: none, if the matrix isn't damaged, like in my use-case where it's shown on a screen), which wasn't easy to find. I didn't find anyone who actually went out into the real world and tried out different settings and different scanning implementations to see what the effect is of choosing a good mask or choosing a good error correction value. In the end, a theoretical answer was enough for my application because I can assume the QRs to be pristine, but in a perfect world we also wouldn't need a mask setting. I then tried to do some research of my own by reading a small QR off my screen with different error correction levels and an intentionally shaking camera to simulate read issues when someone points a smartphone, but found no significant difference between any of the settings. With there being at least four alignment markers, a huge quiet area, and a "timing pattern", does it really matter if there are white blobs due to not having a mask?

(The secondary reason why I gave up trying to read QRs visually is because I noticed they always have the URL written below as fallback anyway. Since then, I did see a few times where there was no fallback, but it's very rare)

Retr0id
7 replies
7h6m

The error correction is funny. If you don't use it, your message takes up less space, and the QR is smaller. If you have a fixed space to fit it in (e.g. printing to a sticker), that means your pixels can be physically bigger. For reliable reading, I found that physically bigger pixels helped more than the error correction itself.

Depending on the length of your message, sometimes you can turn up the error correction level without impacting the final QR dimensions, and in those cases it's a win/win.

londons_explore
6 replies
6h13m

This is actually "cameras can't focus close, and QR scanners aren't good at seeing a code which is tiny in the frame".

By making the pixels of the code bigger, the camera can be a bit blurry to get the code big enough, and then it'll read.

Retr0id
5 replies
5h58m

I mean, that's kinda the whole point? The precise details of the optic path don't really matter, bigger pixels will always be easier to resolve.

One might reasonably expect error correction to help with the decode of blurry inputs, but that wasn't really the case in my experiments.

londons_explore
4 replies
5h20m

The 'proper' fix is to either engineer cameras that can focus closer, or to engineer barcode scanning apps to be able to see a code which is small somewhere in the frame.

I think people are working on both as we speak.

Retr0id
3 replies
4h50m

It doesn't matter how objectively good your camera/decoder is, in absolute terms. There will always be some minimum size or maximum distance, where the detail can no longer be resolved (or errors no longer corrected)

subtra3t
1 replies
4h39m

Why? Is this something that's a side effect of some irrefutable physics law or a limitation of the current technology?

Retr0id
0 replies
4h34m

Both. You can't have a measurable feature smaller than the Planck length, but that's not relevant to QR decoding in any practical sense.

As for the practical limits, try using your phone to take a picture of something very far away, or very tiny, and see what happens.

londons_explore
0 replies
3h7m

If we're talking theory, the pixel size doesn't matter - it's the amount of information encoded in the QR code that matters (ie. excluding ECC bits!). In turn, that means it is theoretically possible to decode a QR code where each 'pixel' of the code is smaller than the pixel of the camera sensor observing the code.

While it is theoretically possible, nobody has yet done so...

RugnirViking
2 replies
6h36m

Last year I did some experimentation along these lines and I also found that no error correction was best, at least when 3d printing QR codes. I was trying to find how small I could print it and still have it be detectable. Like the sibling comment, I suspect it is because of individually larger pixels.

Aachen
1 replies
4h5m

The problem with that, as I understand it, is that your 3d print (or any print or screen) cannot get damaged at all. The pixels being bigger makes it easier to scan ...when it's fully in view and fully intact. Any pixel fails, and you can never recover the original data (besides some guesses, e.g. if the protocol identifier gets damaged a la htwps://)

Error correction doesn't seem to be for easier scanning, but for errors that might occur

(... and stupid logo overlays)

but this information is annoyingly hard to find. Hence my question about the mask xor overlay: does that actually help? Did anyone try it, or did it just sound like a good idea?

RugnirViking
0 replies
2h44m

the idea that a single pixel of the design would get damaged absent the rest seems unlikely. What seems to be more common is that a direction of light/some flaw in the printing process causes many/all pixels to be flawed in the same way past some threshold.

basil-rash
0 replies
52m

The error correction isn't meant for folks like us who think about things like "how can I make this message smaller to increase the readability of the QR code", it's for the people that take their entire tracking parameter-infected URL and dump it into a version 25 (117x117) code and plaster it onto a huge sign out front where a bird promptly shits on it and a teenager slaps a sticker on it and somehow the data remains.

ajsnigrutin
5 replies
6h44m

So is the rest all content? Not quite! There is also error correction, which is used to make sure that the QR code can still be read even if some parts are damaged, blurry, or missing. The error correction is generated by some fancy math, and we don't care about it here for the purpose of reading it by hand.

This should be explained better... I mean sure, the math can be hard.. but is the error correction appended at the end? After every byte? In the middle? Can we still read a qr code by hand if it has error correction (assuming it's not damaged, and we can skip the math part?)?

andirk
3 replies
5h27m

Barcodes use the last digit as a checksum. The checksum is some adding up the numbers and multiplying or something, then % 10 (only 0-9 possible values). As you can see with this math, the error checking has a 1/10 of a chance of coincidentally showing a correct checksum in cases where the data is incorrect. Either way, that last digit on barcodes is insignificant to the actual product's unique barcode ID.

Fun story: The barcode was ripped and the checksum # was frayed off of an item I was returning to Home Depot. I frantically tried to do the math quicker that the checker could manually look it up. But they won and I'll never forget it.

https://www.gs1.org/services/how-calculate-check-digit-manua...

https://www.simplybarcodes.com/barcode_check_digit_calculato...

js2
0 replies
1h22m

Feynman could've done it, with a little luck anyway. :-)

https://www.ecb.torontomu.ca/~elf/abacus/feynman.html

greengrocer4567
0 replies
39m

When I worked at a grocery store in the 2000s, you didn't need the checksum digit when keying in a barcode by hand. In fact, manually entering the checksum digit would result in a "product not found" error.

So I wonder if the checker had to manually look anything up, assuming it was only the checksum digit that was frayed off.

Perhaps some POS systems do require the checksum digit for manually-entered barcodes, though.

epcoa
0 replies
2h29m

A few common barcodes including UPC work this way but mostly this is the exception. The 2D ones being discussed here like QR and Aztec use actual error correcting codes, so none of them. In the linear space Codabar (libraries) is a widely used example that doesn’t. GS-128 doesn’t, etc.

vrighter
0 replies
6h27m

the data in the code is encoded as a bitstream using possibly different alphabets, byte is just one of them.

Then, depending on the size and error correction level (not covered in the article where this is decoded from) the bitstream is split up into blocks, ecc data is calculated for both, and then the blocks are interleaved.

So this method will fail for any qr version above 5 for any level of ecc, and 3-5 with high levels of ecc.

yreg
4 replies
6h13m

My friends often joke that a person who is checking our tickets is able to do precisely this mentally in their head – when that person is satisfied by seeing a QR code rather than scanning it.

It became very popular over here with the Green Passes (EU Digital Covid Vaccination Certificates). Waiters, etc. were supposed to check whether the guests are vaccinated, but 99% of them just demanded any random QR code to be shown to them, took a look at it and considered it done.

Unless we are a country of hidden math geniuses :)

bluGill
3 replies
5h4m

It would probably only take a week of training/practice for someone to get good enough to read them manually. Particularity if the vaccination codes have a common pattern - the same mask, format information and the like. I would expect you can look at a few areas to see if the person is vaccinated (though this wouldn't pick up on someone else's vaccinated status)

mr_mitm
1 replies
4h42m

There is a digital signature embedded in the QR code. No one can verify that in their head.

bluGill
0 replies
2h31m

We don't need to verify everything though, just extract the vaccinated/not field which is probably in the same location on every QR code (or at least it should be possible to make it in the same area), and maybe the name of the person the QR code is for.

tln
0 replies
8m

LOL, the EU's vaccination QR codes are 90+ modules wide, BASE 45 encoded and compressed.

cyco130
4 replies
7h3m

Slightly off topic: One day in the late 90s or early 2000s, I wanted to transfer the contents of my Atari 8-bit disks to my PC. I did know about SIO2PC, a cable that converts between Atari's SIO port and the PC's serial port and a piece of software to go with it. But I didn't have the electronics skills to build one (even though it is actually very easy).

So I ended up writing a Basic program on the Atari to read data from the disk sector by sector and paint it on the screen (with the large 4-color pixels of graphics mode 3). The Atari was connected to the TV card of my PC and a Delphi program I wrote was running on the PC that kept taking screen shots and trying to decode the data from there. I quickly learned that empty sectors threw off my pixel position calibration so I added a mask pattern and a checksum. The sector address was also included. With that, I was able to transfer all my disk contents to my PC. To this day I consider it my greatest engineering achievement :)

Some ten years later, I went on to build an SIO2PC program called AspeQt. A more up-to-date community fork called RespeQt is still the most popular tool in that category used by the community. It even has its own subforum on AtariAge[1].

[1] https://forums.atariage.com/forum/184-respeqt-sio2pc-softwar...

efdee
1 replies
4h53m

Just wanted to say this sounds like a fun project and you must have been pretty happy when it ended up working out!

cyco130
0 replies
2h23m

I was so happy that I'm still boasting about it some 25 years later!

xnx
0 replies
29m

I think there's definitely a future for this type of data exfiltration via display as otherwise locked-down systems become more common.

blakesmith
0 replies
12m

Reminds me of how the first generation iPod firmware and keys were reverse engineered. They blinked out bit patterns on the LCD backlight and used a camera to read the data in! https://mastodon.social/@bagder/111538350617290554

ao98
4 replies
4h32m

Wonderful write up, thank you! One question I’ve been trying to answer: I’ve been seeing more QR codes in the wild using dots instead of squares, and rounded edges instead of hard corners.

All my research suggests these are reader implementation specific and not guaranteed to work per the official spec.

But I find it hard to believe these codes are becoming more prevalent if they aren’t guaranteed to read.

Anyone have more info on this?

kqr
1 replies
4h24m

You'd be surprised how incompetent most adults are at what they do. I'm sure some less technical person assumed QR reading works the same way everywhere, tested it with their device and went "Yess it works! Ship it!"

I also sometimes see QR codes that are inverted. Not all readers detect them but many enough do that they end up in print.

TonyTrapp
0 replies
4h21m

That being said, the QR code readers most people have in their pockets already have to be able to deal with all sorts of problems (blurry pictures, dust on lens, and many more scenarios) that rounded corners are unlikely to have an affect on any of them.

lights0123
0 replies
4h20m

In reality,

- Apple's barcode reader

- Google's ML Kit

- and ZXing, probably behind most third party QR code scanning apps

covers most QR code readers that users will actually use, so testing them is fairly easy.

Isamu
0 replies
3h55m

Rounded corners is handled similarly to blurry images, one of the main ideas is readers to be forgiving in what they accept, and rely on the error detection bits to tell if it is way off. With error correction you can tolerate stylistic mangling.

NeoTar
4 replies
7h1m

Stupid 'trivia' question, but could someone generate the 'darkest' (most black pixels) and 'brightest (most white pixels) QR codes possible?

lekevicius
3 replies
6h58m

It’s of course possible, but the spec is trying to avoid this. There are multiple “masking patterns”, and the algorithm should choose one that gives fewest “penalty points”. Large single color areas are a lot of penalty points, so QR algorithm is trying to avoid them.

Retr0id
1 replies
6h22m

An encoder should try to avoid them, but in theory it doesn't have to, right?

lifthrasiir
0 replies
6h13m

Yeah, it's not mandatory. The specification itself recommends a very concrete algorithm though, and one of its criteria is literally the average density [1].

[1] https://github.com/lifthrasiir/qr.js/blob/52f0409a22c5ece6a5...

NeoTar
0 replies
6h49m

Yes - I think it would be interesting to see them actually produced. Could we get to 60% white pixels? Or 75%?

There could maybe be two solutions:

* Darkest/Brightest allowed by the QR algorithm,

* Darkest/Brightest technically valid, which would would not be chosen by the algorithm (i.e. if one manually chooses the masking pattern.

Perhaps also more solutions - 'Darkest/Brightest recognized by software X/Y/Z'

DerCommodore
2 replies
7h58m

Fun article

ThePowerOfFuet
1 replies
5h10m

This kinda comment is best on reddit, not here. Just use the upvote button and keep the SNR high!

subtra3t
0 replies
4h37m

I like how you were polite instead of lashing out at them and/or flagging the comment.

tylervigen
0 replies
1h52m

This made me very curious about the error correction. Apparently you can design the codes to be variably durable from 7% to 30% recoverable.[0] Neat!

[0] https://docs.beaconstac.com/en/articles/6018654-what-is-erro...

tamarlikesdata
0 replies
4h37m

How do you distinguish different encoding modes (numeric, alphanumeric, byte, etc.) within the data region, especially when dealing with a QR code that uses multiple encoding modes?

platzhirsch
0 replies
22m

This is useful. I tried to scan a QR code with my analog camera and it didn't work. Now I can apply this algorithm to the developed photo myself.

nayuki
0 replies
3h42m

Someone's video on decoding from a decade ago: https://www.youtube.com/watch?v=KA8hDldvfv0 (20 min)

My interactive web page on creating a QR code step by step (so basically the inverse process): https://www.nayuki.io/page/creating-a-qr-code-step-by-step

jr19mi
0 replies
3h52m

Great explanation of how to read QR codes, thanks for the write up! Here's a nice one about 1D codes and how to decode your average UPC codes you find on products in (American) supermarkets:

https://scanbot.io/blog/how-do-barcodes-work/

cybrox
0 replies
2h51m

Everyone praises the writeup itself but the fact that the article dynamically generates all the graphics based on your input is even more awesome!

algem
0 replies
3h0m

pretty cool article

SushiHippie
0 replies
6h14m

Related submissions:

Decoding small QR codes by hand (2012) - https://news.ycombinator.com/item?id=36173441 - Jun 2023 (69 comments)

How a QR code works - https://news.ycombinator.com/item?id=32837565 - Sep 2022 (114 comments)

Creating a QR Code step by step - https://news.ycombinator.com/item?id=24119124 - Aug 2020 (41 comments)

Creating a QR Code step by step - https://news.ycombinator.com/item?id=18360847 - Nov 2018 (34 comments)

DeathArrow
0 replies
4h6m

Looking on Wikipedia I see that QR code was invented in 1994 by a Japanese automotive components manufacturer to label car parts.

I wonder if QR code was invented today, could it be improved? Maybe for compactness? Ease of read?

Crypt0nomicon
0 replies
2h14m

You’ve got to watch out reading those QR codes with your mind as you might contract a lethal mind-virus!

83457
0 replies
40m

My son, a freshman in high school, had an Apple Watch as his first and only device for a while. One big annoyance for him was not being able to scan QR codes that are common in high school where we live. It is an affluent area and the assumption by many, including teachers, is that all of the kids have phones. Not required and they have computers, just comes up regularly.

I was considering doing a project with low quality camera to scan QR codes. We got him a phone before I started down that path.