"Oishi Izumi Suki" Advent Calendar I will be in charge of the 5th day. This is my first time to participate in the Advent calendar. I'm excited.
This time, I will introduce the procedure to create a QR code from scratch without relying on an existing library. Now that the existing libraries are extensive, it is not particularly useful, but please see it as a reading material that feels like QR code is created like this.
We will create a QR code that stores the text "Izumi Oishi" as data, and explain how to read it with an existing QR code reader. The QR code specifications will be explained focusing on only the necessary parts.
First of all, this article is not the original, but a follow-up challenge based on information on sites that are doing similar things on the web.
Create a QR code (http://www.swetake.com/qrcode/qr1.html)
In this article, I will focus on the points that have been blocked while referring to this.
In addition, JIS information, which is a standard, is indispensable for implementing QR codes. You can read the standard document on the JIS site (printing is not possible). Since you cannot get the URL to fly directly, please search the database with "JIS X 0510". The referenced version is "X0510: 2018" updated in 2018.
I got information from many other sites, so I will introduce them at the end of this article.
Although it is a QR code, there are actually many types. There are over 40 versions, from compact and large squares to insanely large and fine-grained ones.
What is different is basically two points, capacity and strength of error correction. The capacity is from 5 bytes to about 3700 bytes, and error correction recovers from 7% to 30% of the total even if a part cannot be read.
This time, I want to make a simple code that only includes the text "Izumi Oishi", so I will select a small one. Specifically, it is a QR code with 25 squares on each side called version 2-H. The capacity is 16 bytes (Table 7 on page 31 of the standard). In addition, we selected the one with the highest error correction power of 30%. Enter 9 characters for kanji and hiragana. "Anastasia Suki" is safe. Unfortunately, "Eve Santa Claus likes" is not included.
The overall data structure for this version is as follows. It looks like this.
The large eye-catching pattern in the three corners is the "position detection pattern" (and the adjacent white "separation pattern"). The pattern like a pedestrian crossing that connects them is the "timing pattern", and the small eyeball on the lower right side is the "alignment pattern". These are called "functional patterns" and are always colored.
On the other hand, the coded area changes depending on the data to be stored. There are three types below.
number | capacity | Details |
---|---|---|
① Data section | 128bit | Contains information about the data to be stored and information to identify its type |
② Error correction symbol | 224bit | ①,Makes it possible to read data correctly even if a certain number of parts (2) fail to be read. |
④ Format information | 15bit | Stores error correction level and mask information. In addition, error correction information other than ② is included so that this information itself may be partially missing. |
Other types of QR codes may have other "model number information", but this time they do not have them, so I will omit them. In addition, there are the following parts.
number | capacity | Details |
---|---|---|
③ Residual bit | 7bit | The remainder of the figure. Fill with bit 0 |
If you can make these, the QR code is complete. It's a long way to go, but please keep in touch.
The detailed structure of the data section is as follows.
Since the capacity of the QR code is valuable, there are several modes that are specialized for the type of data to be entered. This time, select the kanji mode that is specialized for kanji. Only the characters included in the Shift-JIS character code can be used, but this time it is sufficient. The identification code for Kanji mode is 1000
(binary). If you use another mode, you can use Unicode strings.
In Kanji mode, the length of the character string is stored in 8 bits. In other modes it is different from 9 bits or 10 bits. This time it's 5 characters, so it's 00000101
.
The target character type depends on Shift-JIS (UTF-8 has become so popular these days that it is not used much ...). In Shift-JIS, one character is represented by 16 bits, but since it is a little over 7,000 characters in total, it can be represented by 13 bits (2 13 </ sup> = 8096). Follow the steps below to convert the Shift-JIS character code to a dedicated 13-bit code.
conditions | Conversion procedure |
---|---|
Character code is 0x8140 to 0x9FFC In the case of |
1.Subtract 0x8140 2.Add 0xC0 to the high-order byte 3.Add lower byte to upper byte |
Character code is 0xE040-0xEBBF In the case of |
1.Subtract 0xC140 2.Add 0xC0 to the high-order byte 3.Add lower byte to upper byte |
The processing is divided into two types because Shift-JIS itself is roughly divided into two sections (strictly four). (Reference) (or standard P.89)
As a result, "Oishi Izumisuki" is converted as follows.
letter | Shift-JIS(Hexadecimal) | 13-bit code(Binary) |
---|---|---|
Big | 0x91E5 | 0110010100101 |
stone | 0x90CE | 0101111001110 |
Izumi | 0x90F2 | 0101111110010 |
Su | 0x82B7 | 0000100110111 |
Ki | 0x82AB | 0000100101011 |
Information to indicate that this is the end of the data. Fixed to 0000
with 4 bits. However, if the remaining capacity is 3 bits or less, cut part or all of it so that it does not protrude.
~~ It grows grass. ~~ If the total number of bits is not a multiple of 8 in the process up to this point, fill it with grass-filling bits = bit 0
until it becomes a multiple of 8. This time, 4 + 8 + 13 * 5 + 4 = 81 so far, so fill in 7 bits. 0000000
If there is still space left in the process up to this point, 11101100
and 00010001
will be filled alternately until the capacity is full.
To summarize the contents so far
1000
00000101
0110010100101
0101111001110
0101111110010
0000100110111
0000100101011
0000
0000000
11101100
00010001
11101100
00010001
11101100
If you organize it by 8 bits,
10000000
01010110
01010010
10101111
00111001
01111110
01000001
00110111
00001001
01011000
00000000
11101100
00010001
11101100
00010001
11101100
Convert to decimal integer
128
86
82
175
57
126
65
55
9
88
0
236
17
236
17
236
It's done.
This was the most difficult task. In the QR code, an error correction code is added by a method called Reed-Solomon code (hereinafter referred to as RS code) so that the data can be correctly decoded even if part of the data (that is, black or white) cannot be read correctly. This calculation method is very difficult for those who are not good at math.
It's a very long section, so it might be a good idea to skip here first and read to the end.
To put it briefly, the problems that need to be solved here are as follows.
Primitive polynomial x^8+x^4+x^3+x^2+1 was used\\Enlarged Galois GF(2^8)In\\
N = 44, K = 16 \\
I(x) = d_1x^{15}+d_2x^{14}+d_3x^{13}+d_4x^{12}+d_5x^{11}+d_6x^{10}+d_7x^9+d_8x^8 + \\ d_9x^7+d_{10}x^6+d_{11}x^5+d_{12}x^4+d_{13}x^3+d_{14}x^2+d_{15}x+d_{16}
\\
G(x) =
x^{28}+α^{168}x^{27}+α^{223}x^{26}+α^{200}x^{25}+α^{104}x^{24}+α^{224}x^{23}+α^{234}x^{22}+α^{108}x^{21}+ \\
α^{180}x^{20}+α^{110}x^{19}+α^{190}x^{18}+α^{195}x^{17}+α^{147}x^{16}+α^{205}x^{15}+α^{27}x^{14}+ \\α^{232}x^{13}+
α^{201}x^{12}+α^{21}x^{11}+α^{43}x^{10}+α^{245}x^{9}+α^{87}x^{8}+α^{42}x^{7}+ \\
α^{195}x^{6}+α^{212}x^{5}+
α^{119}x^{4} +α^{242}x^{3}+α^{37}x^{2}+α^{9}x +α^{123}
\\When\\
P(x) = x^{N-K} I(x) \quad mod \quad G(x)
\\
Ask for
...
...
...
** What? ** I don't know what it means?
It's tempting to run away while yelling "Murry" when you see a high-order polynomial like a fool, but of course, it's designed to be solvable. I would like to proceed while explaining one by one.
Before we start the problem, I think we need to explain the concept of mathematics called GF (2). I can't explain it because I just remembered it, but to put it simply, it means "a world with special calculation rules that has only two types of numbers, 0 and 1." In this world, the rules of addition and subtraction are as follows.
addition
+ | 0 | 1 |
---|---|---|
0 | 0 | 1 |
1 | 1 | 0 |
subtraction
- | 0 | 1 |
---|---|---|
0 | 0 | 1 |
1 | 1 | 0 |
Yes, addition and subtraction have exactly the same result. Also, as you can see from this result, this matches the XOR (Exclusive OR) of the bits. There is something convenient for the computer around here. By expanding this steadily, various applications will be possible.
By the way, GF is an abbreviation for Galois Field, and in Japanese it is called Galois field or finite field.
Primitive polynomials are special polynomials used to extend and apply GF (p m </ sup>). It is also used to extend GF (2) (p = 2, m = 1).
GF (2 8 </ sup>) is an extension of GF (2), which also has special calculation rules. GF (2) contained only two numbers, 0 and 1, but GF (2 8 </ sup>) contains 2 8 </ sup> = 256 numbers. .. This seems to be often used because it is very convenient for 8-bit arithmetic.
Primitive polynomials are used when extending GF (2) to GF (2 8 </ sup>), but there are several types of primitive polynomials, and which one is used when calculating the RS code. Since the calculation result changes depending on the usage, when creating the QR code, x 8 </ sup> + x 4 </ sup> + x 3 </ sup> + x < You are clearly instructed to use sup> 2 </ sup> + 1.
The α
that appears in the function G (x) is the primitive polynomial F (x) = x 8 </ sup> + x 4 </ sup> + x 3 </ sup> It is the solution when the root of + x 2 </ sup> + 1, that is, F (x) = 0. And it is a very important existence that composes 256 numerical values (also called original in technical terms) included in GF (2 8 </ sup>). Since the property of α is necessary to solve this problem, I will explain it carefully though it is long.
Since α satisfies F (α) = 0, the following equation holds.
α^8+α^4+α^3+α^2+1 = 0 \tag{1}
At this time, all the coefficients of each term belong to the world of GF (2). That is, it takes only two values, 0 and 1, and the result of addition and subtraction is both equal to XOR. Based on that, (1) is transformed.
α^8 = α^4+α^3+α^2+1 \tag{2}
You may think "Hmm?", But it is not a mistake that there is no minus when transposing. Since addition and subtraction are the same, it is safe to say that there is no distinction between +/- in this world (α 8 </ sup> = 1α 8 </ sup> = (0-1) α. 8 </ sup> =-α 8 </ sup>).
The power of α has a very important property. To talk about that, we will first calculate a e </ sup> (e is an integer greater than or equal to 0). α 8 </ sup> is equal to α 4 </ sup> + α 3 </ sup> + α 2 </ sup> + 1, so α 9 </ sup>, α 10 </ sup>, α 11 </ sup>
α^9 = α^5 + α^4 + α^3 + α \\
α^{10} = α^6 + α^5 + α^4 + α^2 \\
α^{11} = α^7 + α^6 + α^5 + α^3 \\
It will be. In α 12 </ sup>
\begin{align}
α^{12} &= α^8 + α^7 + α^6 + α^4 \\
&= (a^4 + a^3 + a^2 + 1) + a^7 + a^6 + a^4 \\
&= a^7 + a^6 + (1+1)a^4 + a^3 + a^2 + 1 \\
&= a^7 + a^6 + a^3 + a^2 + 1
\end{align}
In the third line, 1 + 1 = 0 holds for the coefficient of α, so the term of α 4 </ sup> disappears. As you can see, thanks to the replacement of α 8 </ sup>, no matter how high the degree of α is, it will be at most 8 terms below α 7 </ sup>. Can be replaced.
α^e = b_1α^7 + b_2α^6 + b_3α^5 + b_4α^4 + b_5α^3 + b_6α^2 + b_7α + b_8
b 1 </ sub> ~ b 8 </ sub> is a number (0 or 1) that belongs to GF (2). You can feel the bit operation.
And if you keep increasing the order of α,
α^{255} = 1
Can be obtained. Since α 0 </ sup> = 1, α e </ sup> loops in 255 cycles.
It's been a long time, but here's the most important thing.
*** About α e </ sup> In the range where e is 0 to 254, the coefficients b 1 </ sub> ~ b 8 </ sub> are uniquely determined ** *
In other words, e and b 1 </ sub> ~ b 8 </ sub> can each have a 1: 1 correspondence. It should look like the table below.
e | b1 | b2 | b3 | b4 | b5 | b6 | b7 | b8 |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
2 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
3 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
4 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
7 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 |
9 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 |
... | ||||||||
217 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
218 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
219 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 |
... | ||||||||
252 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 |
253 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 |
254 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 |
All are too long, so only some are listed. Here and [Here (Linked Table 4)](http: / /www.swetake.com/qrcode/qr3.html).
Also, below is the code to generate the table. Only those who want to see it.
Python
# e 0, 1, 2, 3, 4, 5, 6, 7, 8
buffer = [1, 0, 0, 0, 0, 0, 0, 0, 0]
print('e b1 b2 b3 b4 b5 b6 b7 b8 d10')
for e in range(1, 255):
#Shift the buffer to the right
buffer = [0] + buffer[0:8]
if buffer[8]:
buffer[8] = 0
# a^8 has occurred, so a^4+a^3+a^2+a^Replace with 0
added = [1, 0, 1, 1, 1]
for i in range(len(added)):
# GF(2)In the digit-to-digit addition is equal to XOR(And there is no advance)
buffer[i] = buffer[i] ^ added[i]
n = sum([buffer[i] * (2 ** i) for i in range(8)])
print(e, list(reversed(buffer[:8])), n)
With Maxima, you can write in just 5 lines (there is a library that handles GF)
Maxima
load("gf")$
gf_set_data(2, x^8+x^4+x^3+x^2+1)$
binmap(n) := makelist(coeff(gf_exp(x, n), x^k), k, 7, 0, -1)$
exp2num(n) := lreduce(lambda([x,y],2*x+y), binmap(n))$
for n : 0 thru 254 do print(n, binmap(n), exp2num(n));
For α e </ sup>, I found that the same value can be expressed in two ways, e or b 1 </ sub> to b 8 </ sub>. In the article, we will refer to them as ʻe expressionand
b expression`, respectively. The key is how to use these two expressions properly.
I will explain the law of operation between powers of α.
First is multiplication.
When multiplying the two values α i </ sup> and α j </ sup>
α^iα^j = α^{i+j} \tag{3}
It will be. This is a range that I can learn in high school mathematics, so I don't think it's a problem. I will use it later.
Next is addition and subtraction.
α^i + α^j = ? \\
α^i - α^j = ?
This calculation cannot be done with the ʻe expression. But you can do it with
b expression`.
α^i = b_{i1}α^7+b_{i2}α^6+b_{i3}α^5+b_{i4}α^4+b_{i5}α^3+b_{i6}α^2+b_{i7}α+b_{i8} \\
α^j = b_{j1}α^7+b_{j2}α^6+b_{j3}α^5+b_{j4}α^4+b_{j5}α^3+b_{j6}α^2+b_{j7}α+b_{j8} \\
If you leave\\
\begin{align}
α^i + α^j = α^i - α^j &= (b_{i1} \oplus b_{j1})α^7 + (b_{i2} \oplus b_{j2})α^6 + (b_{i3} \oplus b_{j3})α^5 \\
&+ (b_{i4} \oplus b_{j4})α^4 + (b_{i5} \oplus b_{j5})α^3 + (b_{i6} \oplus b_{j6})α^2 \tag{4} \\ &+ (b_{i7} \oplus b_{j7})α + (b_{i8} \oplus b_{j8})
\end{align}
e expression
are equal to the XOR for each coefficient in the b expression
. More simply, it is equal to the XOR of 8 bits in a table
.The necessary tools are available according to equations (3) and (4).
Next, the coefficient d that appears in the function I (x) will be explained.
I will write I (x) again.
I(x) = d_1x^{15}+d_2x^{14}+d_3x^{13}+d_4x^{12}+d_5x^{11}+d_6x^{10}+d_7x^9+d_8x^8 + \\ d_9x^7+d_{10}x^6+d_{11}x^5+d_{12}x^4+d_{13}x^3+d_{14}x^2+d_{15}x+d_{16}
d 1 </ sub> ~ d 16 </ sub> contains the data to be protected by the RS code, that is, the 16 bytes of data obtained in advance, each containing 8 bits. It is a higher-order expression of the variable α that has information. The definition is as follows.
d = b_1α^7 + b_2α^6 + b_3α^5 + b_4α^4 + b_5α^3 + b_6α^2 + b_7α^1 + b_8
Yes, it is the same as the b expression
corresponding to α e </ sup>. Therefore, the input data can be converted to the form of d = α e </ sup> every 8 bits. Let's do it for a moment.
The first 4 bytes of data were 10000000`` 01010110
01010010`` 10101111
. If you convert this while looking at the correspondence table (find the value of e from the right side to the left side),
d_1 = α^7 \\
d_2 = α^{219} \\
d_3 = α^{148} \\
d_4 = α^{97}
(Sorry, d 3 </ sub> and d 4 </ sub> are not listed due to the omission of the table.)
It will convert all the data as well. Only one point needs attention. Since there is no e that makes α e </ sup> = 0 only when the data is 00000000
, I give up and give up the term itself to express this in the form of α e </ sup>. I will cut it.
As a result, I (x) looks like this:
I(x) = α^{7}x^{15}+α^{219}x^{14}+α^{148}x^{13}+α^{97}x^{12}+α^{154}x^{11}+α^{167}x^{10}+α^{191}x^9+α^{185}x^8 + \\ α^{223}x^7+α^{241}x^6+0x^5+α^{122}x^4+α^{100}x^3+α^{122}x^2+α^{100}x+α^{122}
The data corresponding to d 11 </ sub> was 00000000
, so the x 5 </ sup> section disappeared.
Recall the function P (x) we want to find here.
\begin{align}
P(x) &= x^{N-K} I(x) \quad mod \quad G(x) \\
&= x^{28} I(x) \quad mod \quad G(x)
\end{align}
So replace x 28 </ sup> I (x) with another function.
M(x) = x^{28}I(x) \\
= α^{7}x^{43}+α^{219}x^{42}+α^{148}x^{41}+α^{97}x^{40}+α^{154}x^{39}+α^{167}x^{38}+α^{191}x^{37}+α^{185}x^{36} + \\ α^{223}x^{35}+α^{241}x^{34}+0x^{33}+α^{122}x^{32}+α^{100}x^{31}+α^{122}x^{30}+α^{100}x^{29}+α^{122}x^{28}
Then, if you write G (x) again,
G(x) =
α^{0}x^{28}+α^{168}x^{27}+α^{223}x^{26}+α^{200}x^{25}+α^{104}x^{24}+α^{224}x^{23}+α^{234}x^{22}+α^{108}x^{21}+ \\
α^{180}x^{20}+α^{110}x^{19}+α^{190}x^{18}+α^{195}x^{17}+α^{147}x^{16}+α^{205}x^{15}+α^{27}x^{14}+ \\α^{232}x^{13}+
α^{201}x^{12}+α^{21}x^{11}+α^{43}x^{10}+α^{245}x^{9}+α^{87}x^{8}+α^{42}x^{7}+ \\
α^{195}x^{6}+α^{212}x^{5}+
α^{119}x^{4} +α^{242}x^{3}+α^{37}x^{2}+α^{9}x +α^{123}
The pressure is still strong, but it's pretty refreshing.
By the way, how do you find the remainder for a polynomial? I feel like I did it around Number II-B when I was in high school. As a reminder, let's find the remainder of the function m (x) = x 2 </ sup> + 3x + 1 divided by g (x) = x-1.
First, put the formula on the side to be broken.
x^2 + 3x + 1
Then, match the order and coefficient of the formula on the dividing side to the side to be divided.
\begin{align}
& x^2 + 3x + 1 \\
-)& x^2 - x \hspace{2pc} ←xg(x)
\end{align}
And you'll subtract. Erases the highest degree term.
4x + 1
And in the same way,
\begin{align}
& 4x + 1 \\
-)& 4x - 4 \hspace{2pc} ←4g(x)
\end{align}
The remaining ones are below the order of the dividing side, so it ends here. Therefore, the remainder is 5. When the coefficient of the maximum order of g (x) is 1, it is easy to do like this.
You can get P (x) in exactly the same way. Now, let's try to actually divide M (x) by G (x) only at the beginning (sorry, but it's too long to write).
First, check each other's maximum degree terms. M (x) is α 7 </ sup> x 43 </ sup>, and G (x) is α 0 </ sup> x 28 </ sup>. So multiply G (x) by α 7 </ sup> x 15 </ sup> to get the same value.
\begin{align}
& α^{7}x^{43}+α^{219}x^{42}+α^{148}x^{41}+... \\
& α^{7}α^{0}x^{43}+α^{7}α^{168}x^{42}+α^{7}α^{223}x^{41}+... \hspace{2pc} ←α^7x^{15}G(x)
\end{align}
Here we use equation (3). The multiplication of the powers of α is the addition of the exponents, so if you organize it
\begin{align}
& α^{7}x^{43}+α^{219}x^{42}+α^{148}x^{41}+... \\
-)& α^{7}x^{43}+α^{175}x^{42}+α^{230}x^{41}+... \hspace{2pc} ←α^7x^{15}G(x)
\end{align}
Equation (4) is used for this subtraction. Subtraction between powers takes an 8-bit XOR, right? For α 219 </ sup> --α 175 </ sup>, α (01010110 xor 11111111) </ sup> = α 10101001 </ sup> = α 135 </ sup> That's right. α 148 </ sup> --α 230 </ sup> = α 01010010 xor 11110100 </ sup> = α 10100110 </ sup> = α 207 </ sup > .... Be sure to refer to the table when converting from ʻe expression(exponential value) to
b expression (decimal number) and from
b expression to ʻe expression
(decimal number <as is). -> Do not convert to decimal number)
All you have to do now is repeat the process of erasing the highest degree terms. As a caveat, if the exponent becomes 255 or more after using equation (3), use α 255 </ sup> = 1 to correct the exponent to be less than 255. ..
It ends when the side to be finally divided falls below x 28 </ sup>, and R (x) is calculated as follows.
R(x) = α^{248}x^{27}+α^{159}x^{26}+α^{237}x^{25}+α^{105}x^{24}+α^{12}x^{23}+α^{215}x^{22} \\
+α^{172}x^{21}+α^{102}x^{20}+α^{113}x^{19}+α^{149}x^{18}+α^{233}x^{17}+α^{135}x^{16}\\
+α^{51}x^{15}+α^{42}x^{14}+α^{233}x^{13}+α^{7}x^{12}+α^{44}x^{11}+α^{236}x^{10}+α^{216}x^{9} \\
+α^{159}x^{8}+α^{64}x^{7}+α^{70}x^{6}+α^{11}x^{5}+α^{0}x^{4}+α^{51}x^{3}+α^{5}x^{2}+a^{60}x^{1}+a^{168}
What I wanted (RS code) is the exponential value of each coefficient part of this R (x). Therefore
248
159
237
105
12
215
172
102
113
149
233
135
51
42
233
7
44
236
216
159
64
70
11
0
51
5
60
168
It's done. It was tough.
So far, it's about 60-70%. It's a little more.
Arrange the created data and error correction symbols bit by bit according to the image numbers. Since the data is 16 bytes and the error correction symbol is 28 bytes, 44 * 8 = 352 bits. Fill up to 351 in the figure.
I will add color (0 or 1) to the rest
The white part is called the bright module, and bit 0
is inserted.
The black part is called the dark module, and bit 1
is inserted.
The green part is called the residual bit, which is a fractional part, so insert bit 0
.
I will fill in the purple part at the end, but ** I did not know what value to enter at this time, so I will temporarily enter the value TBD
. Please let me know if you are familiar with it **. (The standard (P.45) says that it must be emptied temporarily, but what is it?)
Only the purple part in the figure is temporarily placed, but the figure is completed.
The QR code has a function called "mask" to prevent the contents of the data from generating patterns that are extremely difficult to read. The purpose is to partially invert the arranged black and white patterns using eight different patterns, and finally generate the most readable pattern.
Therefore, in the software (encoder) that creates the QR code, you have to try all eight masks and select the best one.
There are eight types of masks below. (Calculation formula omitted. For details, see P.49 of the standard)
--Data part --Error correction code
--Functional pattern (position detection, timing, alignment) --Format information --Remaining bits
After applying each mask, the score will be evaluated according to four types of evaluation criteria. The evaluation is a deduction method, and the one with the fewest points will be actually used.
The evaluation target is the entire QR code. (However, there is a part where the color has not been decided yet, so it is unclear what to do with it ...)
The evaluation criteria are as follows (Table 11 on page 53 of the standard).
Evaluation number | Evaluation contents(Roughly) | How to deduct points(Roughly) |
---|---|---|
1 | Points will be deducted if there are 5 or more consecutive cells of the same color in the horizontal or vertical direction. Deduction is evaluated only once with the longest consecutive number (Do not deduct points twice for the same square) |
5 times in a row-3 6 times in a row-4 7 times in a row-5 ... |
2 | 2x2 size same color block(Both light and dark)If there is a deduction Count all even if some overlap |
Per one-3 ※1 |
3 | Dark:Ming:Dark:Ming:Dark=1:1:3:1:1 pattern(※2)に隣接する4連続のMingモジュールがある場合減点 | Per one-40 |
4 | Points will be deducted if the ratio of dark modules is biased | 50%From error 5%There is no deduction within. Error 5%Every time it increases-10 |
The explanation here is very rough, so please refer to the standard for the exact contents.
When actually evaluated, only evaluations 1 and 2 were deducted, and evaluations 3 and 4 were not deducted in all eight masks. ** For evaluation 3, the evaluation stopped working at all because I put a value such as value TBD
in the format information part, but what about this ... ** After all, the Ming module Is it appropriate to put in ...?
The mask pattern 111
(bottom right of the image above) was selected with the least goals this time.
Then actually apply the selected mask.
Fill in the last remaining part. What remains is the part called "formal information".
The following two are included in the format information.
--Error correction level (2bit) 10
--Selected mask pattern number (3bit) 111
The error correction level is 10
because'H'was selected this time. For other levels, refer to the standard (P.54, Table 12).
BCH code is calculated based on this 5-bit information 10111
. This is also a type of error correction code similar to the RS code. You might think, "Is it math again?", But it's okay because it's the same process flow and it's pretty easy.
In this case as well, the functions I (x) and G (x) are defined, and the following problems are solved.
N = 15, K=5 \\
I(x) = 1x^4 + 0x^3 + 1x^2 + 1x + 1 \\
G(x) = x^{10} + x^8 + x^5 + x^4 + x^2 + x + 1 \\
In\\
P(x) = x^{N-K}I(x) \quad mod \quad G(X) \\
Ask for
Each coefficient of I (x) is an array of error correction level and mask number bits. Thankfully this time, all the coefficients are 0 or 1, so it's very easy to calculate.
If you write only the result, you will get 0000101001
.
This is connected after the existing 5bit and XORed with the specified mask 101010000010010
to complete.
\begin{array}{c}
\begin{align}
& 101110000101001 \\
\oplus & 101010000010010 \\
\hline
& 000100000111011
\end{align}
\end{array}
The correct values are listed on page 76, Table C.1 of the standard, but they are in good agreement. Was good.
Finally, write the 15 bits of the format information you just obtained to the still empty part.
You need to write the same thing in two different places.
Finally, make an image and you're done. It's easiest to create an image at the same size and enlarge it without interpolation. Don't forget to add at least 4 squares of quiet zone (white margin) around it.
Complete! !! It was a long way to go!
By the way, can you read what you made?
** It's done **.
I tried it on an iPad, Android tablet, and Free software for Windows, but all of them read without problems. .. I didn't expect it to go so smoothly.
By the way, I forgot to mask the format information at first and output it as it is, but it still read it properly. Is the decoder side doing its best to do something about it?
By experiencing the process of actually making a QR code, the article "Reading a QR code manually" that I once read and tilted my head is also "Ah, I was able to feel that I could do it somehow. "
I hope you read this article and think that QR codes are surprisingly easy to create.
The source code (language is Python) created this time has become a little long, so it is on an external site (Github). Please boil or bake. (I think it would be nice to put the QR code on a business card, like P) QR code generator that displays "Izumi Oishi"
I'll put up a reference site and a link that I recommend reading in connection with this article.
Try to make a QR code : The site that I referred to most this time QR Code.com : Denso's site that developed the QR code. I can roughly understand the QR code QR code Deep Dive-data coding and error correction- : The page I found when I almost finished writing this article (lighthouse darkness). I should have searched for the article in Qiita before writing, but I don't understand why I missed it. Creating a QR Code step by step : (English) A great site that illustrates the process of creating a QR code step by step with detailed information.
Galois field and extension field : Easy-to-understand article about Galois body 1 Galois Body Course : Easy-to-understand article about Galois body 2 [Wikipedia-Reed-Solomon Code](https://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%BC%E3%83%89%E3%83%BB%E3%82% BD% E3% 83% AD% E3% 83% A2% E3% 83% B3% E7% AC% A6% E5% 8F% B7 #% E7% AC% A6% E5% 8F% B7% E5% 8C% 96 ) : The formula used in the explanation example is the same as the one used in the QR code, so it is very helpful. Reed–Solomon codes for coders : Although it is in English, it is explained in general, so if you can read it, please do
CRC-32 : This is an explanation slide about CRC-32. CRC, which is often used to check data corruption, is also a technology that uses Galois fields. If you read it together, you will deepen your understanding, maybe. What is Oishi Izumi (Delicious Izumi) [Pixiv Encyclopedia] : For those who are Izumi Oishi
Recommended Posts