Error coding
This section is dedicated to section 8.5 in the specification.
This is the hardest part in my opinion, I will try to make it as clear as possible.
QRCodes use a mechanism called CRC it basically takes the data and computes redundancy from it. Depending on how we compute it, we get bigger data. This is why we can have different L/M/Q/H quality (respectively 7%, 15%, 25% and 30%).
Computing said redundancy allows for a part of the QRCode to be hidden / illegible and still be decodable. When adding an image on a QRCode, we make use of it's redundancy already.
Thanks to the previous step, we have a buffer data. We want to compute redundancy for our buffer. The idea is to use polynomial division.
I summarized information on blocks here. Each Version / ECL gives a different denominator for our polynomial division.
We will go through our buffer by block (groups) and compute for every block the CRC using polynomial division. This polynomial division uses Galois Field (256), which I explain more below.
This following steps are mandatory to begin our divisions.

• Retrieve the generator polynomial, according to Version and ECL.
• Split the data buffer (from previous step) in group 1 and then group 2. (You will need information on blocks).
GP1: [ 64,   0, 236,  17, 236,  17, 236,  17, 236,  17, 236]
GP1: [ 17, 236,  17, 236,  17, 236,  17, 236,  17, 236,  17]


GP2: [236,  17, 236,  17, 236,  17, 236,  17, 236,  17, 236,  17]
GP2: [236,  17, 236,  17, 236,  17, 236,  17, 236,  17, 236,  17]
• Apply division by generator polynomial, on each subgroup.

We Will go back and forth using alpha notation and normal notation. You can find the conversion table in the table section.
The following example is using the first array from the first groupe as data buffer and 2 as polynomial number. But feel free to try different values (shorter in the beginning).

Each step is explained, don't hesitate to click on the [+] to see more

# Initial state

Our polynomial generator:
[  0, 210, 171, 247, 242,  93, 230,  14, 109, 221,  53, 200,  74,   8, 172,  98,  80, 219, 134, 160, 105, 165, 231] = α0x22 + α210x21 + α171x20 + α247x19 + α242x18 + α93x17 + α230x16 + α14x15 + α109x14 + α221x13 + α53x12 + α200x11 + α74x10 + α8x9 + α172x8 + α98x7 + α80x6 + α219x5 + α134x4 + α160x3 + α105x2 + α165x1 + α231x0

Our data buffer:
[ 64,   0, 236,  17, 236,  17, 236,  17, 236,  17, 236] = 64x10 + 0x9 + 236x8 + 17x7 + 236x6 + 17x5 + 236x4 + 17x3 + 236x2 + 17x1 + 236x0

We need to pad with 0s our buffer by the number of the generator polyomial, here 22.

# Padding

Our padded data buffer:
[ 64,   0, 236,  17, 236,  17, 236,  17, 236,  17, 236,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0] = 64x32 + 0x31 + 236x30 + 17x29 + 236x28 + 17x27 + 236x26 + 17x25 + 236x24 + 17x23 + 236x22 + 0x21 + 0x20 + 0x19 + 0x18 + 0x17 + 0x16 + 0x15 + 0x14 + 0x13 + 0x12 + 0x11 + 0x10 + 0x9 + 0x8 + 0x7 + 0x6 + 0x5 + 0x4 + 0x3 + 0x2 + 0x1 + 0x0
[+]
# Division n°1
= [195,  55,  86, 247, 151,  39, 165, 144, 129,  62,  83, 253,  19, 171,  13, 177,  36, 132,  63, 206, 179, 139,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0]
[+]
# Division n°2
= [132, 238, 166, 119, 119, 228, 100, 223,  92,  64,  44, 143, 185,  96,  99, 240,  18, 221, 184, 210, 237, 130,   0,   0,   0,   0,   0,   0,   0,   0,   0]
[+]
# Division n°3
= [ 12, 251, 207, 187,  23,  24, 230, 106, 116,  53,  89,  64,  50, 217, 251, 190, 208, 226,  19,   4, 135, 248,   0,   0,   0,   0,   0,   0,   0,   0]
[+]
# Division n°4
= [112, 200, 225,   4,  35, 226, 190,  59,  46, 164, 208,  16,  69, 245, 141, 184,  45, 194, 216,  63, 122,   8,   0,   0,   0,   0,   0,   0,   0]
[+]
# Division n°5
= [ 29,  38,  54, 116, 136, 101, 248, 115,  88, 209,  57,  48, 172,  30, 121,  33, 253,  63,  87, 110, 137, 171,   0,   0,   0,   0,   0,   0]
[+]
# Division n°6
= [ 13, 125, 117, 228,  71, 243, 153, 181, 171,  86,  97, 127,  82, 239,  21,   3, 175, 125, 146, 150,  93,  22,   0,   0,   0,   0,   0]
[+]
# Division n°7
= [175, 193,  61, 228, 126, 105, 114,  89,   8, 180, 243, 249, 110,  96, 115,  58, 228, 153, 172, 255,   5, 253,   0,   0,   0,   0]
[+]
# Division n°8
= [213, 186,   5,  21, 199,  23, 151,  91,  21, 166,  76, 221, 122,  96,  94,  63, 246,  89, 251, 117, 125, 202,   0,   0,   0]
[+]
# Division n°9
= [ 59, 207, 177, 111, 123,  47, 232, 253,  99,  21, 153, 143, 241, 215,  62, 125,  47, 222, 171, 253,   8, 109,   0,   0]
[+]
# Division n°10
= [192, 148, 238,  19, 221,  10,  39,  25, 164, 111,  49, 195,  82, 116,  86,  51, 181,  37, 254,  44,  13, 217,   0]
[+]
# Division n°11
= [204, 158, 218, 240, 157, 103, 216,  32, 194,  90,  54,  72,  65, 182,  36, 123,  73, 111, 109,  66,  17, 128]
# Result

We have as a final result
[204, 158, 218, 240, 157, 103, 216,  32, 194,  90,  54,  72,  65, 182,  36, 123,  73, 111, 109,  66,  17, 128]
Recap:
We had a single byte buffer. We splitted it into sub-buffers (groups). Each group had it's CRC computed.
We now have 2 buffers for group n°1 and 2 buffers for group n°2.
We have one CRC for each group.
Made with 🚀 by erwanvivien
Catched a mistake ? Please make an issue