this post was submitted on 10 Dec 2024
359 points (98.9% liked)

unix_surrealism

2599 readers
100 users here now

one should not chase the electric dream

This community is for sharing original content related to computers, content, surrealism and wizardry.

Now that you're a surrealist, become a Techno-Mage:

founded 2 years ago
MODERATORS
359
‎ ‎ (lemmy.sdf.org)
submitted 6 months ago* (last edited 6 months ago) by pmjv to c/unix_surrealism
 

made by redruM

all 26 comments
sorted by: hot top controversial new old
[–] sbv@sh.itjust.works 46 points 6 months ago (2 children)

That's some fine error correction.

[–] Karyoplasma@discuss.tchncs.de 19 points 6 months ago (1 children)
[–] Endymion_Mallorn@kbin.melroy.org 2 points 6 months ago (1 children)

Nope, it reads as L-level correction, so up to 7%.

Correct. The author used the long numeric section to encode the data, see my incomplete analysis in another comment.

Actually I think the QR code contains no errors, it's all in the weird numeric data. There are still things I don't understand but see my other comment for analysis.

[–] winety@lemmy.zip 43 points 6 months ago (3 children)

I want this as a sticker on my laptop!

[–] pmjv 19 points 6 months ago
[–] gnemmi 8 points 6 months ago
[–] nickwitha_k 22 points 6 months ago

That's incredible. I knew that QR had error correction capabilities but didn't realize that they were THAT good.

Beautiful.

[–] degen@midwest.social 18 points 6 months ago

It's not a contest, but I think this one wins it for me. I haven't even scanned it yet.

[–] a_robot@lemm.ee 14 points 6 months ago (1 children)

I thought the nose was a mini smiley face.

[–] pmjv 14 points 6 months ago

that's allowed.

[–] RVGamer06@sh.itjust.works 11 points 6 months ago (2 children)
[–] dukatos@lemm.ee 30 points 6 months ago (1 children)
[–] AnarchistArtificer@slrpnk.net 5 points 6 months ago
[–] pmjv 16 points 6 months ago
[–] xmanmonk 9 points 6 months ago

Damn brilliant. That's all I've got to say.

[–] lorty@lemmy.ml 6 points 6 months ago

This is great

[–] Endymion_Mallorn@kbin.melroy.org 2 points 6 months ago (1 children)

Wow, this is only level L according to my device, so it's nominally less than 7% distorted. That's crazy.

But next time, maybe post the URL in the thread title.

[–] pmjv 2 points 6 months ago (2 children)

well, the url has been in the side bar since the beginning

[–] ChaoticNeutralCzech@feddit.org 2 points 1 week ago* (last edited 1 week ago)

side bar

Not really, the text part (blue) takes up half of the right third plus the numeric part (red-orange) takes up most of the rest

[–] Endymion_Mallorn@kbin.melroy.org 0 points 6 months ago (1 children)

Fair enough, but I personally don't like unverified QR codes. I've had experiences with QR stuff and I've switched over to using an entirely offline program to decode them because of it.

[–] ChaoticNeutralCzech@feddit.org 2 points 2 weeks ago

unverified

It's not about verification but accessibility

[–] ChaoticNeutralCzech@feddit.org 2 points 1 week ago* (last edited 1 week ago)

Contrary to popular belief, this wasn't made by making a very error-resistant code and sticking an image on top, as most "Logo-QR" codes are made today. AFAIK, the code is not only error-free but also up to spec*, unlike this Bad Apple one that, while also impressive, uses non-standard padding bytes after the actual data.

* Except the XOR mask pattern is not chosen to minimize problematic patterns like solid color areas in the result, obviously – but I'm not buying a $270 standard just to see if it says "should" or "must".

https://analognowhere.com/#815956000955341196626324525376426508044011799516042661339518686677364520931952256954853578523008163894957991180853268570682643959895730628162682682661506593341503383997517938597366696669325062682725512003951964556693309309170041341332991998000490597366

The URL is very interesting. I'm trying to reverse-engineer the creation process of this code.

  • The version (size) is 6 (41×41), just small enough to not have alignment patterns (extra squares).
  • The masking pattern is 2, probably since that encodes as 3 black pixels as part of the picture.
  • The error correction is set to the minimum or L, allowing the maximum possible number of bytes to be user-controlled. The number of content bits is 1088. Since one byte is used for length, the longest string that can be encoded is 134 bytes.

Here it is "unmasked":

There can be multiple data types in a QR code. This one first has a bytes section, which readers interpret as text, and then a numeric section. Blue is the text part of the URL, red-orange is the numeric part, and green is error correction.
The raw data in the QR code is:

0b 0100                    Encoding: Bytes (Latin-1 text)
0b 00011011                Content Length: 27
0x 68 74 74 70 73 3A 2F 2F "https://"
0x 61 6E 61 6C 6F 67 6E 6F "analogno"
0x 77 68 65 72 65 2E 63 6F "where.co"
0x 6D 2F 23                "m/#"
0b 0001                    Encoding: Numeric
0b 0011111100              Content Length: 252
0b 1100101111              [815]
0b 1110111100              [956]
0b 0000000000              [000]
0b 1110111011              [955]
0b 0101010101              [341]
0b 0011000100              [196]
0b 1001110010              [626]
0b 0101000100              [324]
0b 1000001101              [525]
0b 0101111000              [376]
0b 0110101010              [426]
0b 0111111100              [508]
0b 0000101100              [044]
0b 0000001011              [011]
0b 1100011111              [799]
0b 1000000100              [516]
0b 0000101010              [042]
0b 1010010101              [661]
0b 0101010011              [339]
0b 1000000110              [518]
0b 1010101110              [686]
0b 1010100101              [677]
0b 0101101100              [364]
0b 1000001000              [520]
0b 1110100011              [931]
0b 1110111000              [952]
0b 0100000000              [256]
0b 1110111010              [954]
0b 1101010101              [853]
0b 1001000010              [578]
0b 1000001011              [523]
0b 0000001000              [008]
0b 0010100011              [163]
0b 1101111110              [894]
0b 1110111101              [957]
0b 1111011111              [991]
0b 0010110100              [180]
0b 1101010101              [853]
0b 0100001100              [268]
0b 1000111010              [570]
0b 1010101010              [682]
0b 1010000011              [643]
0b 1110111111              [959]
0b 1101111111              [895]
0b 1011011010              [730]
0b 1001110100              [628]
0b 0010100010              [162]
0b 1010101010              [682]
0b 1010101010              [682]
0b 1010010101              [661]
0b 0111111010              [506]
0b 1001010001              [593]
0b 0101010101              [341]
0b 0111110111              [503]
0b 0101111111              [383]
0b 1111100101              [997]
0b 1000000101              [517]
0b 1110101010              [938]
0b 1001010101              [597]
0b 0101101110              [366]
0b 1010111000              [696]
0b 1010011101              [669]
0b 0101000101              [325]
0b 0000111110              [062]
0b 1010101010              [682]
0b 1011010101              [725]
0b 1000000000              [512]
0b 0000000011              [003]
0b 1110110111              [951]
0b 1111000100              [964]
0b 1000101100              [556]
0b 1010110101              [693]
0b 0100110101              [309]
0b 0100110101              [309]
0b 0010101010              [170]
0b 0000101001              [041]
0b 0101010101              [341]
0b 0101001100              [332]
0b 1111011111              [991]
0b 1111100110              [998]
0b 0000000000              [000]
0b 0111101010              [490]
0b 1001010101              [597]
0b 0101101110              [366]
0b 0000                    End
0b 00

Note that the numeric encoding uses 10 bits for each group of 3 digits. Let's call it triplet-BCD. The last two bits are only to round up the data section to a whole number of bytes, specifically these 88 bytes:

41 B6 87 47 47 07 33 A2 
F2 F6 16 E6 16 C6 F6 76 
E6 F7 76 86 57 26 52 E6 
36 F6 D2 F2 31 3F 32 FE 
F0 00 EE D5 53 12 72 51 
20 D5 E1 AA 7F 02 C0 2F 
1F 81 02 AA 55 53 81 AA 
EA 95 6C 82 3A 3E E1 00 
EE B5 59 0A 0B 02 0A 3D 
FB BD F7 CB 4D 55 0C 8E 
AA AA 0F BF DF ED A9 D0 
A2 AA AA AA 55 FA 94 55 
57 DD 7F F9 60 5E AA 55 
5B AB 8A 75 45 0F AA AB 
56 00 00 FB 7F 12 2C AD 
53 54 D4 AA 0A 55 55 33 
DF F9 80 07 AA 55 5B 80

What follows in the QR code is error correction bytes, 36 of them. The numbers in the right and mid-upper section of the image must have been chosen so that the error correction bytes end up forming the left half of the face, presumably via lots of trial-and-error. However, what I find very odd is that the decimal number the numeric section encodes, which you see at the end of the URL, translates to this in hex:

0x1c7dbd97f32cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

This is not a floating point error, the triplet-BCD-encoded data really produces 501222037467851 × 2^788^, a very round number in binary!! I have no idea how that coincides with so many digits being used as part of the face in the weird triplet-BCD encoding.

Also, I haven't been able to replicate the error correction algorithm: I think it's the same as reedsolo in Python but

>>> from reedsolo import RSCodec
>>> rawbytes=b"\x41\xB6\x87\x47\x47\x07\x33\xA2\xF2\xF6\x16\xE6\x16\xC6\xF6\x76\xE6\xF7\x76\x86\x57\x26\x52\xE6\x36\xF6\xD2\xF2\x31\x3F\x32\xFE\xF0\x00\xEE\xD5\x53\x12\x72\x51\x20\xD5\xE1\xAA\x7F\x02\xC0\x2F\x1F\x81\x02\xAA\x55\x53\x81\xAA\xEA\x95\x6C\x82\x3A\x3E\xE1\x00\xEE\xB5\x59\x0A\x0B\x02\x0A\x3D\xFB\xBD\xF7\xCB\x4D\x55\x0C\x8E\xAA\xAA\x0F\xBF\xDF\xED\xA9\xD0\xA2\xAA\xAA\xAA\x55\xFA\x94\x55\x57\xDD\x7F\xF9\x60\x5E\xAA\x55\x5B\xAB\x8A\x75\x45\x0F\xAA\xAB\x56\x00\x00\xFB\x7F\x12\x2C\xAD\x53\x54\xD4\xAA\x0A\x55\x55\x33\xDF\xF9\x80\x07\xAA\x55\x5B\x80"
>>> rsc = RSCodec(36); print(rsc.encode(rawbytes).hex())
41b68747470733a2f2f616e616c6f676e6f77686572652e636f6d2f2313f32fef000eed55312725120d5e1aa7f02c02f1f8102aa555381aaea956c823a3ee100eeb5590a0b020a3dfbbdf7cb4d550c8eaaaa0fbfdfeda9d0a2aaaaaa55fa945557dd7ff9605eaa555bab8a75450faaab560000fb7f122cad5354d4aa0a555533dff98007aa555b80662d719c3ef320500601c1e3f6fd3b517a3e1f06c9a7d4140c7c78af219b3b39f5dd2053

does not yield the expected error correction bytes I can see in the unmasked code (green)...