[PYTHON] Créez un code QR qui affiche "Izumi Oishi" en grattant

Calendrier de l'Avent "Izumi Oishi" Je serai en charge du 5ème jour. C'est la première fois que je participe au calendrier de l'Avent. Je suis surexcité.

Cette fois, je présenterai la procédure pour créer un code QR à partir de zéro sans compter sur la bibliothèque existante. Ce n'est pas particulièrement utile maintenant que les bibliothèques existantes sont étendues, mais voyez-le comme un matériel de lecture qui vous donne l'impression que le code QR est créé comme ça.

À propos du contenu de cet article

Nous allons créer un code QR qui stocke le texte «Izumi Oishi» sous forme de données, et expliquer comment le lire avec un lecteur de code QR existant. Les spécifications du code QR seront expliquées en se concentrant uniquement sur les pièces nécessaires.

Site référencé

Tout d'abord, cet article n'est pas l'original, mais un défi de suivi basé sur des informations sur des sites qui font des choses similaires sur le Web.

Créez un code QR (http://www.swetake.com/qrcode/qr1.html)

Dans cet article, je me concentrerai sur ce qui est bloqué en y faisant référence.

De plus, les informations JIS, qui sont un standard, sont indispensables pour la mise en œuvre des codes QR. Vous pouvez lire la norme sur le site JIS (l'impression n'est pas possible). Puisque vous ne pouvez pas obtenir l'URL pour voler directement, veuillez rechercher la base de données avec "JIS X 0510". La version référencée est «X0510: 2018» mise à jour en 2018.

J'ai obtenu des informations sur de nombreux autres sites, je vais donc les présenter à la fin de cet article.

Décidez du type de code QR

Bien qu'il s'agisse d'un code QR, il existe en fait de nombreux types. Il existe plus de 40 versions, des carrés compacts et grands à ceux incroyablement grands et fins.

Ce qui est différent, ce sont essentiellement deux points, la capacité et la force de la correction d'erreur. La capacité est de 5 octets à environ 3700 octets, et la correction d'erreur récupère de 7% à 30% du total même si une pièce ne peut pas être lue.

Cette fois, je veux créer un code simple qui n'inclut que le texte "Izumi Oishi", je vais donc en sélectionner un petit. Plus précisément, il s'agit d'un code QR avec 25 carrés de chaque côté appelé version 2-H. La capacité est de 16 octets (Tableau 7 à la page 31 de la norme). De plus, nous avons sélectionné celui avec le pouvoir de correction d'erreur le plus élevé de 30%. 9 caractères peuvent être saisis pour les kanji et hiragana. "Anastasia Suki" est en sécurité. Malheureusement, "Eve Santa Claus likes" n'est pas inclus.

La structure globale des données pour cette version est la suivante. ss01.png Ça ressemble à ça. figure-layout.png

Les grands motifs accrocheurs dans les trois coins sont le "motif de détection de position" (et le "motif de séparation" blanc adjacent). Le motif comme un croisement qui les relie est le "motif de synchronisation", et le petit globe oculaire en bas à droite est le "motif d'alignement". Ceux-ci sont appelés «motifs fonctionnels» et sont toujours colorés.

En revanche, la zone codée change en fonction des données stockées. Il existe trois types ci-dessous.

nombre capacité Détails
① Section des données 128bit Contient des informations sur les données à stocker et des informations pour identifier leur type
② Symbole de correction d'erreur 224bit ①,Permet de lire correctement les données même si la partie (2) ne parvient pas à lire un certain nombre
④ Informations sur le format 15bit Stocke le niveau de correction d'erreur et les informations de masque. De plus, des informations de correction d'erreur différentes de ② sont incluses de sorte que ces informations elles-mêmes peuvent être partiellement manquantes.

D'autres types de codes QR peuvent avoir d'autres "informations sur le numéro de modèle", mais je les omettrai car ce n'est pas à cette époque. De plus, il y a les parties suivantes.

nombre capacité Détails
③ Bit résiduel 7bit Le reste de la figure. Remplir avec le bit 0

Si vous pouvez les faire, le code QR est complet. C'est un long chemin à parcourir, mais veuillez rester en contact.

Préparer des données pouvant être incluses dans QR

La structure détaillée de la section de données est la suivante.

ss02.png

Type de mode

La capacité du code QR étant précieuse, il existe plusieurs modes spécialisés pour le type de données à saisir. Cette fois, sélectionnez le mode kanji spécialisé pour les kanji. Seuls les caractères inclus dans le code de caractères Shift-JIS peuvent être utilisés, mais cette fois c'est suffisant. Le code d'identification pour le mode Kanji est «1000» (binaire). Si vous utilisez un autre mode, vous pouvez utiliser des chaînes Unicode.

nombre de mots

En mode Kanji, la longueur de la chaîne de caractères est stockée sur 8 bits. Dans d'autres modes, il est différent de 9 bits ou 10 bits. Cette fois, c'est 5 caractères, donc c'est «00000101».

Données de caractère

Le type de caractère cible dépend de Shift-JIS (UTF-8 est devenu si populaire ces jours-ci qu'il n'est pas beaucoup utilisé ...). Dans Shift-JIS, un caractère est représenté par 16 bits, mais comme c'est un peu plus de 7 000 caractères au total, il peut être représenté par 13 bits (2 13 </ sup> = 8096). Suivez les étapes ci-dessous pour convertir le code de caractère Shift-JIS en un code 13 bits dédié.

conditions Procédure de conversion
Le code de caractère va de 0x8140 à 0x9FFC
Dans le cas de
1.Soustraire 0x8140
2.Ajoutez 0xC0 à l'octet de poids fort
3.Ajouter l'octet inférieur à l'octet supérieur
Le code de caractère est 0xE040 ~ 0xEBBF
Dans le cas de
1.Soustraire 0xC140
2.Ajoutez 0xC0 à l'octet de poids fort
3.Ajouter l'octet inférieur à l'octet supérieur

Le traitement est divisé en deux types car Shift-JIS lui-même est à peu près divisé en deux sections (strictement quatre). (Référence) (ou standard P.89)

En conséquence, "Oishi Izumisuki" est converti comme suit.

lettre Shift-JIS(Hexagone) Code 13 bits(Binaire)
Gros 0x91E5 0110010100101
calcul 0x90CE 0101111001110
Izumi 0x90F2 0101111110010
Su 0x82B7 0000100110111
Ki 0x82AB 0000100101011

Modèle de terminaison

Information pour indiquer que c'est la fin des données. Fixé à «0000» avec 4 bits. Cependant, si la capacité restante est inférieure ou égale à 3 bits, coupez-la en partie ou en totalité pour qu'elle ne dépasse pas.

Morceau d'herbe enterré

~~ Il fait pousser de l'herbe. ~~ Si le nombre total de bits n'est pas un multiple de 8 dans le processus jusqu'à ce point, remplissez-le avec des bits de remplissage = "bit 0" jusqu'à ce qu'il devienne un multiple de 8. Cette fois, 4 + 8 + 13 * 5 + 4 = 81 jusqu'à présent, remplissez donc 7 bits. «0000000»

Morsure d'herbe enterrée

S'il reste de l'espace dans le processus jusqu'à ce point, «11101100» et «00010001» seront remplis en alternance jusqu'à ce que la capacité soit pleine.

finalement

Pour résumer le contenu jusqu'à présent

1000 00000101 0110010100101 0101111001110 0101111110010 0000100110111 0000100101011 0000 0000000 11101100 00010001 11101100 00010001 11101100

Si vous organisez par 8 bits
10000000 01010110 01010010 10101111 00111001 01111110 01000001 00110111 00001001 01011000 00000000 11101100 00010001 11101100 00010001 11101100

Convertir en entier décimal
128 86 82 175 57 126 65 55 9 88 0 236 17 236 17 236

C'est fait.

Calculer le code de correction d'erreur (très difficile)

C'était la tâche la plus difficile. Dans le code QR, un code de correction d'erreur est ajouté par une méthode appelée lire le code solomon (ci-après dénommé code RS) afin que les données puissent être correctement décodées même si une partie des données (c'est-à-dire, noir ou blanc) ne peut pas être lue correctement. Cette méthode de calcul est très difficile pour ceux qui ne sont pas bons en mathématiques.

C'est une très longue section, donc ce serait peut-être une bonne idée de passer d'abord ici et de lire jusqu'à la fin.

problème

Pour le dire brièvement, les problèmes qui doivent être résolus ici sont les suivants.


Polypoly primitif x^8+x^4+x^3+x^2+1 a été utilisé\\Galois GF agrandi(2^8)Dans\\
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}
\\Quand\\
P(x) = x^{N-K} I(x) \quad mod \quad G(x) 
\\ 
Demander

...

...

...
** Quelle? ** Je ne sais pas ce que cela signifie?

Il est tentant de s'enfuir en criant «Murry» quand vous voyez un polypole de haut niveau comme un imbécile, mais bien sûr, il est conçu pour être résolu. Je voudrais continuer en expliquant un par un.

À propos de GF2

Avant de se lancer dans le problème, je pense qu'il est nécessaire d'expliquer le concept de mathématiques appelé GF (2). Je ne peux pas l'expliquer parce que je viens de m'en souvenir, mais en un mot, cela signifie "un monde avec des règles de calcul spéciales qui n'a que deux types de nombres, 0 et 1." Dans ce monde, les règles d'addition et de soustraction sont les suivantes.

une addition

+ 0 1
0 0 1
1 1 0

soustraction

- 0 1
0 0 1
1 1 0

Oui, l'addition et la soustraction ont exactement le même résultat. De plus, comme vous pouvez le voir à partir de ce résultat, cela correspond au XOR (somme logique exclusive) des bits. Il y a quelque chose de pratique pour l'ordinateur ici. En développant régulièrement cela, diverses applications seront possibles.

À propos, GF est une abréviation de Galois Field, et en japonais, on l'appelle une forme Galois ou une forme finie.

À propos des polynômes primitifs et de GF (2 8 </ sup>)

Les polynomies primitives sont des polynomies spéciales utilisées pour étendre et appliquer GF (p m </ sup>). Il est également utilisé pour étendre GF (2) (p = 2, m = 1).

GF (2 8 </ sup>) est une extension de GF (2), qui a également des règles de calcul spéciales. GF (2) ne contenait que deux nombres, 0 et 1, tandis que GF (2 8 </ sup>) contenait 2 8 </ sup> = 256 nombres. .. Cela semble être souvent utilisé car il est très pratique pour l'arithmétique 8 bits.

Lors de l'extension de GF (2) à GF (2 8 </ sup>), nous utilisons des polynômes primitifs, mais il existe plusieurs types de polynomies primitives, et celle qui est utilisée lors du calcul du code RS. Étant donné que le résultat du calcul change en fonction de l'utilisation, lors de la création du code QR, x 8 </ sup> + x 4 </ sup> + x 3 </ sup> + x < Il vous est clairement demandé d'utiliser sup> 2 </ sup> + 1.

Qu'est-ce que α?

Le «α» qui apparaît dans la fonction G (x) est le polymorphe primitif F (x) = x 8 </ sup> + x 4 </ sup> + x 3 </ sup> La racine de + x 2 </ sup> + 1, c'est-à-dire la solution lorsque F (x) = 0. Et c'est une existence très importante qui compose les 256 valeurs numériques (appelées aussi l'original en termes techniques) contenues dans GF (2 8 </ sup>). Puisque les propriétés de α sont nécessaires pour résoudre ce problème, je vais l'expliquer en détail pendant longtemps.

Puisque α satisfait F (α) = 0, l'équation suivante est vraie.

α^8+α^4+α^3+α^2+1 = 0 \tag{1}

A ce moment, tous les coefficients de chaque terme appartiennent au monde de GF (2). Autrement dit, il ne prend que deux valeurs, 0 et 1, et le résultat de l'addition et de la soustraction est égal à XOR. Sur cette base, (1) est transformé.

α^8 = α^4+α^3+α^2+1 \tag{2}

Vous pensez peut-être "Hmm?", Mais ce n'est pas une erreur qu'il n'y a pas de moins lors du transfert. Étant donné que l'addition et la soustraction sont les mêmes, il est sûr de dire qu'il n'y a pas de distinction entre +/- dans ce monde (α 8 </ sup> = 1α 8 </ sup> = (0-1) α. 8 </ sup> = -α 8 </ sup>).

Trouvez la puissance de α

La puissance de α a une propriété très importante. Pour en parler, nous allons d'abord calculer un e </ sup> (e est un entier supérieur ou égal à 0). α 8 </ sup> est égal à α 4 </ sup> + α 3 </ sup> + α 2 </ sup> + 1, donc α 9 </ sup>, α 10 </ sup>, α 11 </ sup>

α^9 = α^5 + α^4 + α^3 + α \\
α^{10} = α^6 + α^5 + α^4 + α^2 \\
α^{11} = α^7 + α^6 + α^5 + α^3 \\

Ce sera. Dans α 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}

Dans la troisième ligne, 1 + 1 = 0 vaut pour le coefficient α, donc le terme α 4 </ sup> disparaît. Comme vous pouvez le voir, grâce au remplacement de α 8 </ sup>, quelle que soit la hauteur de l'ordre de α, il sera au plus 8 termes en dessous de α 7 </ sup>. Peut être remplacé.

α^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> est un nombre (0 ou 1) qui appartient à GF (2). Vous pouvez sentir le calcul des bits.

Et si vous continuez à augmenter l'ordre de α,

α^{255} = 1

Peut être obtenu. Puisque α 0 </ sup> = 1, α e </ sup> boucle en 255 cycles.

Cela fait longtemps, mais voici le plus important.

*** À propos de α e </ sup> Dans la plage où e est de 0 à 254, les coefficients b 1 </ sub> ~ b 8 </ sub> sont déterminés de manière unique ** *

En d'autres termes, e et b 1 </ sub> ~ b 8 </ sub> peuvent chacun avoir une correspondance 1: 1. Cela devrait ressembler au tableau ci-dessous.

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

Tous sont trop longs, donc seuls certains sont répertoriés. Ici et [Ici (tableau lié 4)](http: / /www.swetake.com/qrcode/qr3.html).

Vous trouverez également ci-dessous le code pour générer la table. Seuls ceux qui veulent le voir.

<détails>

Générateur de tableaux </ summary>
Version Python

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):
    #Déplacez le tampon vers la droite
    buffer = [0] + buffer[0:8]
    if buffer[8]:
        buffer[8] = 0
        # a^8 s'est produit, donc un^4+a^3+a^2+a^Remplacer par 0
        added = [1, 0, 1, 1, 1]
        for i in range(len(added)):
            # GF(2)Dans, l'ajout de chiffres est égal à XOR(Et il n'y a pas d'avance)
            buffer[i] = buffer[i] ^ added[i]
    n = sum([buffer[i] * (2 ** i) for i in range(8)])
    print(e, list(reversed(buffer[:8])), n)

Avec Maxima, vous pouvez écrire en seulement 5 lignes (il existe une bibliothèque qui gère 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));

Pour α e </ sup>, j'ai trouvé que la même valeur peut être exprimée de deux manières, e ou b 1 </ sub> à b 8 </ sub>. Dans l'article, nous les appellerons respectivement «e expression» et «b expression». La clé est de savoir comment utiliser correctement ces deux expressions.

A propos du calcul des puissances de α

J'expliquerai la loi de calcul entre les puissances de α.

Le premier est la multiplication.

Lors de la multiplication des deux valeurs α i </ sup> et α j </ sup>

α^iα^j = α^{i+j} \tag{3}

Ce sera. Je pense que ce n'est pas un problème parce que c'est une gamme qui peut être apprise même en mathématiques au secondaire. Je l'utiliserai plus tard.

Viennent ensuite l'addition et la soustraction.

α^i + α^j = ? \\
α^i - α^j = ?

Ce calcul ne peut pas être fait avec l '«expression e». Mais vous pouvez le faire avec 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} \\
Si tu pars\\
\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}
  • In 〇 est un symbole représentant XOR (somme logique exclusive). Cela signifie que l'addition et la soustraction dans «l'expression e» sont égales au XOR pour chaque coefficient de «l'expression b». Plus simplement, il est égal à "XOR" entre 8 bits dans une table.

Les outils nécessaires sont disponibles selon les équations (3) et (4).

Qu'est-ce que d?

Ensuite, le coefficient d qui apparaît dans la fonction I (x) sera expliqué.

J'écrirai à nouveau I (x).

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> contient les données à protéger par le code RS, c'est-à-dire les 16 octets de données obtenus à l'avance, dont chacun équivaut à 8 bits. C'est une expression d'ordre supérieur de la variable α qui contient des informations. La définition est la suivante.

d = b_1α^7 + b_2α^6 + b_3α^5 + b_4α^4 + b_5α^3 + b_6α^2 + b_7α^1 + b_8

Oui, c'est la même chose que l'expression «b» correspondant à α e </ sup>. Par conséquent, les données d'entrée peuvent être converties sous la forme d = α e </ sup> tous les 8 bits. Faisons-le un instant.

Les 4 premiers octets de données étaient «10000000» 01010110 »« 01010010 »10101111». Si vous essayez de convertir cela en regardant la table de correspondance (trouvez la valeur de e du côté droit vers le côté gauche),

d_1 = α^7 \\
d_2 = α^{219} \\
d_3 = α^{148} \\
d_4 = α^{97}

(Désolé, d 3 </ sub> et d 4 </ sub> ne sont pas répertoriés en raison de l'omission du tableau.)

Il convertira toutes les données de la même manière. Un seul point mérite attention. Puisqu'il n'y a pas de e qui rend α e </ sup> = 0 uniquement lorsque les données sont «00000000», je renonce à l'exprimer sous la forme de α e </ sup> et du terme lui-même. Je vais le couper.

En conséquence, je (x) ressemble à ceci:

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}

La donnée correspondant à d 11 </ sub> était "00000000", donc la section x 5 </ sup> a disparu.

Trouvez le reste P (x)

Rappelez la fonction P (x) que vous souhaitez trouver ici.

\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}

Remplacez donc x 28 </ sup> I (x) par une autre fonction.

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}

Ensuite, si vous écrivez à nouveau G (x),

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}

La pression est toujours forte, mais c'est plutôt rafraîchissant.

Au fait, comment trouvez-vous le reste d'un polynôme? J'ai l'impression de l'avoir fait autour du numéro II-B quand j'étais au lycée. Pour rappel, trouvons le reste de la fonction m (x) = x 2 </ sup> + 3x + 1 divisé par g (x) = x-1.

Tout d'abord, mettez la formule du côté à casser.

x^2 + 3x + 1

Ensuite, faites correspondre l'ordre et le coefficient de la formule du côté de division au côté à diviser.

\begin{align}
  & x^2 + 3x + 1 \\
-)& x^2 -  x     \hspace{2pc} ←xg(x)
\end{align}

Et vous soustrayez. Efface le terme d'ordre le plus élevé.

4x + 1

Et de la même manière,

\begin{align}
  & 4x + 1 \\
-)& 4x - 4     \hspace{2pc} ←4g(x)
\end{align}

Les autres sont en dessous de l'ordre du côté divisé, donc cela se termine ici. Par conséquent, le reste est de 5. Lorsque le coefficient de l'ordre maximum de g (x) est 1, c'est facile de faire comme ça.

Vous pouvez obtenir P (x) exactement de la même manière. Maintenant, essayons de diviser M (x) par G (x) seulement au début (désolé, mais tout est trop long à écrire).

Tout d'abord, vérifiez les conditions de commande maximales de chacun. M (x) est α 7 </ sup> x 43 </ sup>, et G (x) est α 0 </ sup> x 28 </ sup>. Par conséquent, multipliez G (x) par α 7 </ sup> x 15 </ sup> pour faire correspondre la même valeur.

\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}

Ici, nous utilisons l'équation (3). Multiplier les puissances de α est l'addition d'exposants, donc si vous l'organisez

\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}

L'équation (4) est utilisée pour cette soustraction. La soustraction entre les puissances prend un XOR 8 bits. Pour α 219 </ sup> --α 175 </ sup>, α (01010110 xor 11111111) </ sup> = α 10101001 </ sup> = α 135 </ sup> C'est vrai. α 148 </ sup> --α 230 </ sup> = α 01010010 xor 11110100 </ sup> = α 10100110 </ sup> = α 207 </ sup > .... Assurez-vous de vous référer au tableau lors de la conversion de «e expression» (valeur exponentielle) en «b expression» (binaire), et lors de la conversion de «b expression» en «e expression» (tel quel, nombre décimal < -> Ne pas convertir en nombre binaire)

Il ne vous reste plus qu'à répéter le processus d'effacement des termes d'ordre le plus élevé. En guise de mise en garde, si l'exposant devient 255 ou plus après avoir utilisé l'équation (3), utilisez α 255 </ sup> = 1 pour corriger l'exposant pour qu'il soit inférieur à 255. ..

Il se termine lorsque le côté à diviser finalement tombe en dessous de x 28 </ sup>, et R (x) est calculé comme suit.

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}

Ce que je voulais (code RS), c'est la valeur exponentielle de chaque partie de coefficient de ce R (x). Donc

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

C'est fait. C'était dur.

Placer les données et le code de correction d'erreur dans la masse

Jusqu'à présent, c'est environ 60 à 70%. C'est un peu plus.

Organisez les données créées et les symboles de correction d'erreur bit par bit en fonction des nombres de l'image. Étant donné que les données sont de 16 octets et que le symbole de correction d'erreur est de 28 octets, 44 * 8 = 352 bits. Remplissez jusqu'à 351 dans la figure.

figure-layout-2.png

J'ajouterai de la couleur (0 ou 1) au reste La partie blanche est appelée module lumineux et le "bit 0" est inséré. La partie noire est appelée le module sombre et le "bit 1" est inséré. La partie verte est appelée le bit résiduel, qui est une partie fractionnaire, insérez donc «bit 0». Je remplirai la partie violette à la fin, mais ** je ne savais pas quelle valeur entrer pour le moment, donc je vais temporairement entrer la `valeur à déterminer '. S'il vous plaît laissez-moi savoir si vous le connaissez **. (La norme (P.45) dit qu'il doit être vidé temporairement, mais qu'est-ce que c'est?)

Seule la partie violette de la figure est temporairement placée, mais la figure est terminée.

Choisir le bon masque (difficile)

Le code QR a une fonction appelée «masque» pour éviter que le contenu des données ne génère des motifs extrêmement difficiles à lire. Le but est d'inverser partiellement les motifs en noir et blanc disposés en utilisant huit motifs différents, et enfin de générer le motif le plus lisible.

Par conséquent, dans le logiciel (encodeur) qui crée des codes QR, vous devez essayer les huit masques et sélectionner le meilleur.

Type de masque

Il existe huit types de masques ci-dessous. (Formule de calcul omise. Pour plus de détails, voir P.49 de la norme) masks.png

Pièce à inclure dans la cible du masque

--Partie de données --Code de correction d'erreur

Pièces non incluses dans la cible du masque (autres que celles énumérées ci-dessus)

  • Modèle fonctionnel (détection de position, synchronisation, alignement)
  • Informations sur le format --Bits restants

Évaluation

Après application de chaque masque, le score sera évalué selon quatre types de critères d'évaluation. L'évaluation est une méthode de déduction, et celle avec le moins de points sera effectivement utilisée.

La cible de l'évaluation est le code QR complet. (Cependant, il y a une partie où la couleur n'a pas encore été décidée, donc on ne sait pas quoi en faire ...)

Les critères d'évaluation sont les suivants (Tableau 11 à la page 53 de la norme).

Numéro d'évaluation Contenu de l'évaluation(Grossièrement) Comment déduire des points(Grossièrement)
1 Des points seront déduits s'il y a 5 carrés consécutifs ou plus de la même couleur dans le sens horizontal ou vertical.
La déduction n'est évaluée qu'une seule fois avec le numéro consécutif le plus long
(Ne déduisez pas de points deux fois pour le même carré)
5 fois de suite-3
6 fois de suite-4
7 fois de suite-5
...
2 2x2 taille même bloc de couleur(À la fois clair et sombre)S'il y a une déduction
Comptez tout même si certains se chevauchent
Par un-3
※1
3 Sombre:Ming:Sombre:Ming:Sombre=1:1:3:1:1 motif(※2)に隣接する4連続のMingモジュールがある場合減点 Par un-40
4 Des points seront déduits si le ratio de modules sombres est biaisé 50%De l'erreur 5%Il n'y a pas de déduction à l'intérieur. Erreur 5%Chaque fois qu'il augmente-10

L'explication ici est très approximative, veuillez donc vous référer à la norme pour le contenu exact.

  • 1 Des points seront toujours déduits (-36 points au total) pour le motif de module noir 3x3 sombre à l'intérieur du motif de détection de position dans les trois coins. Cependant, comme aucun masque n'est appliqué à cette partie, les points seront déduits de manière égale dans l'évaluation des huit masques, de sorte que le résultat de la sélection du masque ne sera pas affecté.
  • 2 Fait référence au grand motif de détection de position aux trois coins.

Lorsqu'elles ont été réellement évaluées, seules les évaluations 1 et 2 ont été déduites, et les évaluations 3 et 4 n'ont pas été déduites dans les huit masques. ** Pour l'évaluation 3, j'ai mis une valeur telle que `valeur à déterminer 'dans la partie informations de format, donc l'évaluation a cessé de fonctionner du tout, mais qu'en est-il de cela ... ** Après tout, le module lumineux Est-il approprié de mettre ...?

Le motif de masque "111" (en bas à droite de l'image ci-dessus) a été sélectionné avec le moins de buts cette fois. Ensuite, appliquez réellement le masque sélectionné.

Calculer les informations de format

Remplissez la dernière partie restante. Reste la partie appelée «information formelle».

Les deux suivants sont inclus dans les informations de format.

  • Niveau de correction d'erreur (2 bits) 10
  • Numéro de modèle de masque sélectionné (3 bits) 111

Le niveau de correction d'erreur est «10» car j'ai sélectionné «H» cette fois. Pour les autres niveaux, reportez-vous à la norme (P.54, Tableau 12).

Le code BCH est calculé sur la base de ces informations à 5 bits «10111». Il s'agit également d'un type de code de correction d'erreur similaire au code RS. Vous pourriez penser: "Est-ce encore des mathématiques?", Mais ce n'est pas grave parce que c'est le même flux de processus et c'est assez facile.

Code BCH

Dans ce cas également, les fonctions I (x) et G (x) sont définies et les problèmes suivants sont résolus.

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 \\
Dans\\
P(x) = x^{N-K}I(x) \quad mod \quad G(X) \\
Demander

Chaque coefficient de I (x) est un tableau de bits de niveau de correction d'erreur et de numéro de masque. Heureusement cette fois, tous les coefficients sont 0 ou 1, donc c'est très facile à calculer.

Si vous n'écrivez que le résultat, vous obtiendrez «0000101001». Connectez-le après le 5 bits existant et prenez le XOR avec le masque spécifié 101010000010010 pour terminer.

\begin{array}{c}
\begin{align}
  & 101110000101001 \\
\oplus & 101010000010010 \\
\hline
& 000100000111011
\end{align}
\end{array}

Les valeurs correctes sont répertoriées à la page 76, tableau C.1 de la norme, mais elles sont en bon accord. C'était bien.

Placer les informations de format dans la masse

Enfin, écrivez les 15 bits des informations de format que vous venez d'obtenir dans la partie encore vide.

figure-layout-3.png

Vous devez écrire la même chose à deux endroits différents.

Créer une image de code QR

Enfin, créez une image et vous avez terminé. Il est plus simple de créer une image de même taille et de l'agrandir sans interpolation. N'oubliez pas d'ajouter au moins 4 carrés de zone tranquille (marge blanche) autour d'elle.

izumi_ohishi.png

Achevée! !! C'était un long chemin à parcourir!

Contrôle de fonctionnement

Au fait, pouvez-vous lire ce que vous avez fait?

ss05.png ss06.png

** C'est fait **.

Je l'ai essayé sur iPad, tablette Android et Logiciel gratuit pour Windows, mais ils ont tous lu sans problème. .. Je ne m'attendais pas à ce que ça se passe si bien.

Au fait, j'ai oublié de masquer les informations de format au début et de les sortir telles quelles, mais elles les lisent toujours correctement. Le côté décodeur fait-il de son mieux pour y remédier?

Impressions

En expérimentant le processus de création d'un code QR, l'article "Lire le code QR manuellement" que j'ai lu une fois et j'ai incliné la tête disait également "Ah, J'ai pu sentir que je pouvais le faire d'une manière ou d'une autre.

J'espère que vous avez lu cet article et que vous pensez que le code QR est étonnamment facile à créer.

Le code source (le langage est Python) créé cette fois-ci est devenu un peu long, il se trouve donc sur un site externe (Github). Veuillez faire bouillir ou cuire au four. (Je pense que ce serait bien de mettre le code QR sur une carte de visite, comme P) Générateur de code QR qui affiche "Izumi Oishi"

Lien de référence

Je publierai les sites auxquels j'ai fait référence et les liens que je recommande de lire en relation avec cet article.

Code QR en général

Essayez de créer un code QR : Le site auquel j'ai le plus fait référence cette fois QR Code.com : Site de Denso qui a développé le code QR. Je peux à peu près comprendre le code QR Code QR Deep Dive-data coding or error correction- : La page que j'ai trouvée quand j'ai presque fini d'écrire cet article (l'obscurité des phares). J'aurais dû chercher l'article dans Qiita avant d'écrire, mais je ne comprends pas pourquoi je l'ai manqué. Creating a QR Code step by step : (Anglais) Un excellent site qui illustre le processus de création d'un code QR étape par étape avec des informations détaillées.

Code RS lié

Galoa et élargi : Article facile à comprendre sur le corps Galois 1 Cours corporel Galoa : Article facile à comprendre sur le corps Galois 2 [Wikipedia-Lead 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 ) : La formule utilisée dans l'exemple d'explication est la même que celle utilisée dans le code QR, elle est donc très utile. Reed–Solomon codes for coders : Bien qu'il soit en anglais, il est expliqué en général, donc si vous pouvez le lire, veuillez le faire

Autre

CRC-32 : Ceci est une diapositive d'explication sur CRC-32. Le CRC, qui est souvent utilisé pour vérifier la corruption des données, est également une technologie qui utilise Galois. Si vous le lisez ensemble, vous approfondirez peut-être votre compréhension. Qu'est-ce que Oishi Izumi (Delicious Izumi) [Encyclopédie Pixiv] : Pour ceux qui sont Izumi Oishi

Recommended Posts

Créez un code QR qui affiche "Izumi Oishi" en grattant
Créons une base de données clients où le code QR est automatiquement émis en Python
Créez un code QR pour l'URL sous Linux
Créez le code qui renvoie "A et prétendant B" en python
Créez une application qui saisit, affiche et supprime des formulaires à l'aide de Python / Flask au lieu de DB.
Créer un nouveau dict qui combine des dictés
[Python] Créez un LineBot qui s'exécute régulièrement
Créez un bot qui stimule les tendances Twitter
[Exemple de code Pandas] Création et agrégation d'exemples de données qui ressemblent à un journal d'achat
Créez un BOT qui affiche le nombre de personnes infectées dans le nouveau Corona
[Django] Créez un formulaire qui remplit automatiquement l'adresse à partir du code postal