QRコードの概要
符号化(エンコード)
エラー訂正の概要
エラー訂正に必要な「行列」の解説
「行列」を使ってエラー訂正をしよう
リード・ソロモン符号とエラー訂正の方法
多項式の割り算
リード・ソロモン符号の作り方
ガロア理論と体
QRコードを作ろう
QRコードメーカー
独極・QRコード担当の「あじな」です。
非常に長い解説記事になっちまいましたが、ついに最終段階のQRコードを作る手順に差し掛かりました。
最終段階といっても、皆さん安心してください!なんたって、複雑なことはこれまでにすべて解説し終わっています。
あとは、いままで解説したことを使って作っていくだけです。

これまでの復習 [表示する]

  1. QRコードは株式会社デンソーが作ったもので、スマホや携帯で読み取れる
  2. QRコードは「小さな白と黒の四角でできている」「多少汚れても大丈夫」という特徴がある
  3. 白黒の四角を使うのは、コンピュータにわかりやすくさせるため
  4. QRコードは「機能パターン」と「符号化領域」で出来上がっている
  5. 「機能パターン」は、「クワイエットゾーン」「位置検出パターン」「位置検出パターンの分離パターン」「タイミングパターン」「位置合わせパターン」の5種類
  6. 「符号化領域」は「形式情報」「型番情報」「データ領域」の3種類
  7. 「形式情報」は「エラー訂正レベル」と「マスクパターン参照子」で決まり、「\(4 \times 8=32\)」種類のパターンがある
  8. 「型番情報」は「QRコードのバージョンによって決まり、40種類ある
  9. 「データ領域」は「データ」と「エラー訂正情報」で出来上がる
  10. QRコードはバージョンが1〜40まである。一辺の大きさは、「QRコードのバージョン(1〜40)\( \times \)4\( + \)17」
  11. 「エラー訂正レベル」は「L(7%の汚れまで)」「M(15%の汚れまで)」「Q(25%の汚れまで)」「H(30%の汚れまで)」の4種類ある。
  12. 「エラー訂正レベル」が「L」だと「QRコード」で表現できるデータの量は最大で、「H」のときに最小になる。
  13. 「1bit」とは白・黒、1・0のような2種類の情報を表すことができる能力のことで、文字を増やすと「2bit(4種類)」「3bit(8種類)」と表現できる種類が増える
  14. 日常の言葉を「エンコード」して「コード(符号)」に置き換え、「コード(符号)」を「デコード」して日常の言葉に戻す
  15. QRコードの「エンコード」方式は「数字モード」「英数字モード」「漢字モード」「8bitモード」の4種類
  16. どの「エンコード」方式でも、データは「モード指示子」+「文字数指示子」+「データ」+「終端パターン」+「埋め草ビット」+「埋め草ワード」となる
  17. QRコードには「白」と「黒」を読み間違えても、元の情報を復元する「エラー訂正」能力が備わっている
  18. 「エラー訂正」は読み取れた(聞き取れた)言葉から最も近い「ありえそうな単語」を推測すること
  19. 「エラー訂正力が強い」ということは、「あえて使っていない単語が多い」ということと同じで、効率性は悪い
  20. 1,0でできている符号では「ハミング距離(2つの符号間で1と0が異なる箇所の個数)」があり、符号間で最も「ハミング距離」が小さいものを「最小距離」と呼ぶ
  21. 使える「単語」を制限すると「最小距離」は大きくなる
  22. 「最小距離」の半分までのエラーであれば訂正することができる
  23. 「単語」を「符号化」したものに、適当な「1」や「0」を後ろにつけると「最小距離」が大きい「エラー訂正機能付符号」になる
  24. 「エラー訂正機能付符号」を作る際は「符号」に「行列(生成行列)」を掛け算する。
  25. 「QRコード」は「リード・ソロモン符号」と呼ばれる方法で「エラー訂正機能付符号」を作る
  26. 「行列」は数字を並べただけのもので、もともとは「連立方程式」の係数だけ抜き取ってならべたもの
  27. 「行列」の「足し算」「引き算」は各「行列」の要素同士を「足し算」「引き算」したもの
  28. 「行列」の「掛け算」は、左の「行列」から「行」を取り出し、右の「行列」から「列」を取り出して、それぞれの要素を掛け算して足し合わせる
  29. 左の「行列」の大きさが「a行b列」で、右の「行列」の大きさが「b行c列」だった時、「掛け算」結果の行列は「a行c列」になる
  30. 「行列」の「掛け算」は順番を変えると結果も変わる
  31. 「掛け算」しても結果を変えない行列を「単位行列」と呼び、「掛け算」すると結果が「単位行列」になる行列を「逆行列」と呼ぶ
  32. 「行列」の特徴を表している「数字」を「行列式」と呼ぶ。「行列式」は「正方行列」だけが持っている
  33. 「並び替え」は「置換」によってい表すことができ、偶数回の「置換」でできる「並び替え」を「遇置換」、奇数回の「置換」でできる「並び替え」を「奇置換」という
  34. 「行列式」は各列から数字を選択し「掛け算」し、符号をつけた(「遇置換→(+)」「奇置換→(-)」たものを全ての選択パターンで足し合わせる。
  35. 「列」で計算しても、「行」で計算しても結果は同じ
  36. 「全てが0の列」、もしくは、「すべてが0の行」があれば「行列式」は「0」
  37. 「列」を入れ替えたら「行列式」の符号が変わる。「行」を入れ替えても「行列式」の符号が変わる。
  38. 全く同じ「行」が2個以上あれば「行列式」は「0」。全く同じ「列」が2個以上あっても「行列式」は「0」
  39. ある「行列」の「行列式」は、その「行列」の1つの「列」(もしくは「行」)を2つに分割して、2つの「行列」の「行列式」の「足し算」にすることができる
  40. ある「行」に違う「行」を「足し引き」しても、「行列式」の結果は変わらない。ある「列」に違う「列」を「足し引き」しても、「行列式」の結果は変わらない。
  41. ある「行(もしくは列)」を「定数倍」した「行列」の「行列式」は、「定数倍」する前の「行列」の「行列式」に定数をかけたものと同じ
  42. 2つの「行列」を「掛け算」した結果の「行列」の「行列式」と、それぞれの「行列」の「行列式」を「掛け算」した結果は同じ\(( \left| \boldsymbol{A} \times \boldsymbol{B} \right| = \left| \boldsymbol{A} \right| \times \left| \boldsymbol{B} \right| )\)
  43. 「連立方程式」の係数を抜き出した「行列」の「行列式」の値が「0」になるということは、元の「連立方程式」が「不良設定問題」である
  44. 「逆行列」は「正方行列」かつ「行列式」の値が「0」でない「行列」だけに存在する
  45. 「\((-1)^{(i+j)} \times (元の行列からi行目とj列目を取り去った行列) \)」を「余因子行列」と呼ぶ
  46. 「行列式」は「余因子展開」を使うと、1サイズ小さい「行列」の「行列式」の「足し算」に展開することができる
  47. 「逆行列」は「(元の「行列」の「行列式」の逆数)\(\times\)(x行・y列目の要素が<元の行列のy行・x列目を取り除いた「余因子行列」の「行列式」>となる「行列」)」
  48. 「階段行列」は上の行から、左側(0の部分を除きます)を1にして、その行より下の行の左側が0になるように適当な数字をかけて足し算・引き算するというのを繰り返して作る
  49. 「ランク」はその「行列」の中の独立した行(または列)の数で、「連立方程式」の係数を「行列」にした場合、未知数の数より「ランク」が低ければ「不良設定問題」となる
  50. 「符号」のサイズが1行n列、「エラー訂正付符号」のサイズが1行m列のとき、「生成行列」はn行m列になる
  51. 「QRコード」で利用される「エラー訂正機能付符号」は「リード・ソロモン符号」と呼ばれるもの
  52. 「検査行列」を「エラー訂正機能付符号」に「掛け算」すると結果は「ゼロ行列」になる。逆に「ゼロ行列」にならないと、読み取った「エラー訂正機能付符号」が間違っている
  53. エラー訂正機能のスペックは「n(「エラー訂正機能付符号」の「長さ」)」、「k(実質的に単語を表現する桁数)」、「d(「エラー訂正機能付符号」の間の「最小距離」)」の3つ
  54. エラー訂正機能のスペックの「n(「エラー訂正機能付符号」の「長さ」)」は「検査行列」の行数と同じ
  55. エラー訂正機能のスペックの「k(「実質的に単語を表現する桁数)」は「検査行列」をn行m列だとすると、「n-(検査行列のランク)」となる
  56. 同じ仲間の「エラー訂正機能付符号」を2つ用意すると、それらを「引き算」した結果も同じ仲間の「エラー訂正機能付符号」の1つになる
  57. 「エラー訂正機能付符号」軍団の中の「最小距離」は、その「エラー訂正機能付符号」軍団の中で最も小さい「ハミング重み」と同じになる
  58. エラー訂正機能のスペックの「d(「エラー訂正機能付符号」の間の「最小距離」)」は「(「検査行列」の「ランク」)+1」以上となる
  59. 「シングルトン限界式」は「d(「エラー訂正機能付符号」の間の「最小距離」)」が「n(「エラー訂正機能付符号」の「長さ」)-k(実質的に単語を表現する桁数)+1」以下になること
  60. リード・ソロモンの「検査行列」は、x行y列の要素が\(\alpha^{(x-1)(y-1)}\)で、xはn行まで、yは2t列までの「行列」
  61. リード・ソロモンの「検査行列」のランクは2t
  62. リード・ソロモンの「検査行列」の特徴は、「エラー訂正機能付符号」の「長さ」はn、実質的に単語を表現する桁数)はn-2t、「エラー訂正機能付符号」の間の「最小距離」は2t+1
  63. 「ヴァンデルモンド行列」の行列式は、行列の要素に同じ値のものがなければ「0」にはならない。
  64. 受信符号に検査行列を掛け算した結果は、発生したエラーに検査行列を掛けたものと同じになる、「\(\boldsymbol{Y} \times \boldsymbol{H} = \boldsymbol{E} \times \boldsymbol{H}\)」
  65. 「\(\boldsymbol{Y} \times \boldsymbol{H} = \boldsymbol{E} \times \boldsymbol{H}\)」を展開すると、方程式の数がn個、未知数が2t個の連立方程式になる
  66. リード・ソロモン符号の解き方は、「01.エラーの発生個数」「02.エラーの発生位置」「03.エラーの内容」の3ステップ
  67. \(\begin{vmatrix} S_0 & S_1 & \ldots & S_{j-1} \\ S_1 & S_2 & \ldots & S_{j} \\ \vdots & \vdots & \ddots & \vdots \\ S_{j-1} & S_{j} & \ldots & S_{ 2j-2 } \\ \end{vmatrix}\)という行列式の\(j\)の値を\(t\)から1つずつ減らしていき、初めて行列式の値が「0」以外になった時の\(j\)がエラーの発生個数になる。
  68. エラーが発生している位置に対応する\(\alpha\)の「逆数」(つまり、\(\alpha^{-p_0},\alpha^{-p_1},\cdots ,\alpha^{-p_{j-2}},\alpha^{-p_{j-1}}\)を入力したときだけ「0]を出力する関数を、\(\boldsymbol{Y} \)と\(\boldsymbol{H}\)の情報から作ることができ、エラーの位置を求めることができる
  69. エラーの位置が分かった状態であれば、元の「\(\boldsymbol{Y} \times \boldsymbol{H} = \boldsymbol{E} \times \boldsymbol{H}\)」を普通の連立方程式のように解くことができ、「エラーの内容」を求めることができる
  70. 多項式を多項式で割り算することができ、割り算した商を\(Q(x)\)、余りを\(R(x)\)とすると、「\(f(x) = g(x)Q(x) + R(x)\)」と書ける
  71. 次数が\(f\)の多項式を次数が\(g\)の多項式で割り算すると余りの多項式の次数は\(g\)未満になる
  72. 多項式\(f(x)\)の解(\(f(a)=0\)となる\(a\)の値)を使うと、\(f(x)=(x-a)R(x)\)と因数分解できる(剰余の定理)
  73. 多項式\(f(x)\)は\(f(x) = (x-a_1)(x-a_2)(x-a_3) \cdots (x-a_{(n-2)})(x-a_{(n-1)})(x-a_{n})\)と因数分解できる(ただし、\(a\)は複素数になることもある)
  74. \(x_0\)〜\(x_{(n-1)}\)を係数にもつ\(n-1\)次の多項式\((f(z)=z^0 x_0 + z^1 x_1 + z^2 x_2 + \cdots + z^{(n-3)} x_{(n-3)} + z^{(n-2)} x_{n-2} + z^{(n-1)}x_{(n-1)})\)を\((z-\alpha^0)(z-\alpha^1)(z-\alpha^2) \cdots (z-\alpha^{(2t-3)})(z-\alpha^{(2t-2)})(z-\alpha^{(2t-1)})\)で割り切ることができれば、\(x_0\)〜\(x_{(n-1)}\)はリード・ソロモン符号
  75. メッセージ多項式\((m(z)=z^0 m_0 + z^1 m_1 + z^2 m_2 + \cdots + z^{(k-3)} m_{(k-3)} + z^{(k-2)} m_{(k-2)} + z^{(k-1)}m_{(k-1)})\)に\(z^{2t}\)を掛けて、\((z-\alpha^0)(z-\alpha^1)(z-\alpha^2) \cdots (z-\alpha^{(2t-3)})(z-\alpha^{(2t-2)})(z-\alpha^{(2t-1)})\)で割り算した余り\(R(z)\)の多項式の係数を、元のメッセージ符号に付け加えると、リード・ソロモン符号になる
  76. 「01.加法と乗法が定義されている」「02.演算が閉じている」「03.結合法則が成り立つ」「04.単位元がある」「05.逆元がある」「06.可換である」の6個のルールを満たす集合を「体」と呼ぶ
  77. 「体」であれば、その集合はここで解説している符号化やエラー訂正の理論がそのまま適用できる
  78. QRコードは8桁の多項式(\(ax^7+bx^6+cx^5+dx^4+ex^3+fx^2+gx+h\)を要素とする「体」を使ってリード・ソロモン符号の計算をする

QRコード作成の概要

さぁ、ここでクイズです。この連載のテーマはなんでしょ〜うか?
え?行列のわけわからん説明だっけ?
よっと。冗談きついですよ。QRコードですよ。さんざん遠回りしたから忘れた人も多いかと思って・・・

今回の解説からは、今までのながーい解説を基礎として、QRコードを具体的に作る方法について説明していきますね。
「QRコードを作ってる!」って実感できるように頑張ります。
QRコードは、次のような流れで作ります。
  1. QRコードに入れる文字を決める
  2. エラー訂正レベル決める
  3. 符号化方式を決める
  4. QRコードのバージョンを決める
  5. バージョンにあった枠を作る
  6. 文字を符号化する
  7. 「符号」から「リード・ソロモン符号」を計算する
  8. データをQRコードのデータ領域に書き込む
  9. マスク適用する
さぁ、今回から順を追って解説していきましょう。

QRコードに入れる文字を決める

これがないと、何も始まりませんね。
「QRコード」の中に埋め込む「文字」を決めましょう。文字はアルファベットでも数字でもひらがなでも、漢字でもなんでもOKです。
この解説では「QRコードを独学でマスター」という文字を入れることにしましょう。

ちなみに、「http://www.google.co.jp/」というのような文字をQRコードの中に入れると、QRコードを読み取ったときにそのホームページが勝手に開かれることがあります。
これは、QRコードの機能ではなく、QRコード読み取りソフトウェアのおせっかい機能なので読み取るソフトウェアによっては勝手に開かない場合もあります。
(「xxx@gmail.com」というような文字がQRコードの中にあると、勝手にメール作成画面が開くQRコード読み取りソフトウェアもあります)

エラー訂正レベル決める

次に、QRコードが汚れて全部読み取れなくても、元の文字を復元することができる機能(エラー訂正 )のレベルを決めます。
エラー訂正レベルはこちらで解説しておりますが、レベルL(7%の汚れまでOK)、レベルM(15%の汚れまでOK)、レベルQ(25%の汚れまでOK)、レベルH(30%の汚れまでOK)の4段階で決めます。
すでに「リード・ソロモン」によるエラー訂正機能付符号を習得した皆様なら、ピンとくるかもしれませんが、リードソロモン符号の検査行列は、\((n,n-2t,2t)\)という特徴を持っていました。
これは、エラー訂正機能付符号の長さが\(n\)で、単語を実質的に表す桁数は\(n-2t\)、エラー訂正機能付符号間の最小距離は\(2t\)というものでした。検査行列は次のようなものでしたね。
$$ \begin{pmatrix} 1 & 1 & 1 & \cdots & 1 & 1 & 1 \\ 1 & \alpha & \alpha^2 & \cdots & \alpha^{(2t-3)} & \alpha^{(2t-2)} & \alpha^{(2t-1)} \\ 1 & \alpha^2 & \alpha^4 & \cdots & \alpha^{2(2t-3)} & \alpha^{2(2t-2)} & \alpha^{2(2t-1)} \\ \vdots & \vdots & \vdots & \cdots & \vdots & \vdots & \vdots \\ 1 & \alpha^{(n-3)} & \alpha^{2(n-3)} & \cdots & \alpha^{(n-3)(2t-3)} & \alpha^{(n-3)(2t-2)} & \alpha^{(n-3)(2t-1)} \\ 1 & \alpha^{(n-2)} & \alpha^{2(n-2)} & \cdots & \alpha^{(n-2)(2t-3)} & \alpha^{(n-2)(2t-2)} & \alpha^{(n-2)(2t-1)} \\ 1 & \alpha^{(n-1)} & \alpha^{2(n-1)} & \cdots & \alpha^{(n-1)(2t-3)} & \alpha^{(n-1)(2t-2)} & \alpha^{(n-1)(2t-1)} \\ \end{pmatrix} $$ この検査行列、行数を調整すれば\(n\)(エラー訂正機能付符号の大きさ)を好きに調整できますし、列数を調整すれば\(2t\)(最小距離)を好きに調整できます。
ちなみに、「最小距離の半分」がエラー訂正が可能なエラーの数だったこともあわせて思い出しましょう。つまり、このリード・ソロモンの検査行列で訂正可能なエラーの数は\(t\)なのです。

エラー訂正レベルの話に戻ると、レベルL〜Hまでで、このリード・ソロモンの検査行列の大きさを変えているのです。
レベルLの場合は比較的少ない列数(\(t\)が小さい)ですし、レベルHの場合は比較的多い列数(\(t\)が大きい)を使っているのです。
ちなみに、\(t\)が大きければ大きいほどエラー訂正可能な数は増える(エラー訂正レベルはLからHになっていく)のですが、それにつれて、実質的に単語を表す\(n-2t\)はどんどん小さくなっていくので、エラー訂正レベルがHの場合はLの場合とくらべて実質的に単語を表す桁数は少ない(少ない文字数しか入らない)ことになります。

だから、もし、エラーが発生しないのであれば、より多くの文字が入る「エラー訂正レベルL」を選択するのがよいのですが、いくらたくさん文字が入ってもエラーが発生して読めなくなっては元も子もないので、実際にQRコードを使う環境を想像して適切なレベルを選択するのがよいと思います。

今回のサンプルでは「エラー訂正レベルM」を選ぶことにしましょう。

符号化方式を決める

さて、次に符号化方式を決めましょう。
これは、難しいことを考えなくても次のフローに沿って決めることができます。

Step1 文字の中に「半角数字」しかない場合・・・「数字モード」 もし「半角数字」以外がある場合はStep2へ
Step2 文字の中に「半角数字」と「大文字の半角アルファベット」と「記号」しかない場合・・・「英数字モード」 もし左記以外の文字がある場合はStep3へ
Step3 文字の中に「半角文字」がない場合・・・・「漢字モード」 もし「半角文字」がある場合はStep4へ
Step4 Step1〜Step4に当てはまらない場合「8bitモード」

ちなみに「半角文字」というのは「A」とか「3」といった「幅が小さい文字」のことで、「全角文字」というのは「A」とか「3」といった「幅が大きい文字」のことを言います。

今回の練習用の文字「QRコードを独学でマスター」だと・・・
Step1は「半角数字」以外があるので、Step2へ
Step2は「半角数字」と「大文字の半角アルファベット」以外の文字があるからStep3へ
Step3は「半角文字」がある(「QR」が「半角文字」)のでStep4へ
Step4 Step1〜Step4に当てはまらない場合「8bitモード」

ということで、「8bitモード」で符号化することになります。

QRコードのバージョンを決める

QRコードでは、「誤り訂正レベル」と「符号化方式」と「文字数」が決まれば、最適なバージョンを決めることができます。
具体的には、次の4個の表を見てバージョンを決めます。まず、自分が見たい「誤り訂正レベル」に対応する表を選んでください。
次に、自分が選択した「符号化方式」に対応する列を見て、丁度自分がQRコードに入れたい文字数よりも少し大きめの行を選びます。
そして、表の一番左にあるバージョンを見て、自分のQRコードのバージョンを決めます。
今回のサンプルでは、「誤り訂正レベルはM」で「符号化方式は8bit」で「文字数は24」です。(文字数は8bitモードの場合、全角文字は1字で2文字分カウントすることをに注意してくださいね)
そのため、QRコードのバージョンは「2」であることがわかります。
さて、次回は「バージョンにあった枠を作る」方法についてみていきましょう。

■誤り訂正レベルLの場合■
数字英数字漢字8bitバージョン
412510171
774720322
1277732533
18711448784
255154651065
322195821346
370224951547
4612791181928
5523351412309
65239516727110
77246819832111
88353522636712
102261926242513
110166728245814
125075832052015
140885436158616
154893839764417
1725104644271818
1903115348879219
2061124952885820
2232135257292921
24091460618100322
26201588672109123
28121704721117124
30571853784127325
32831990842136726
35172132902146527
36692223940152828
390923691002162829
415825201066173230
441726771132184031
468628401201195232
496530091273206833
525331831347218834
552933511417230335
583635371496243136
615337291577256337
647939271661269938
674340871729280939
708942961817295340


■誤り訂正レベルMの場合■
数字英数字漢字8bitバージョン
34208141
633816262
1016126423
1499038624
20212252845
255154651066
293178751227
365221931528
4322621111809
51331113121310
60436615525111
69141917728712
79648320433113
87152822336214
99160025441215
108265627745016
121273431050417
134681634556018
150090938462419
160097041066620
1708103543871121
1872113448077922
2059124852885723
2188132656191124
2395145161499725
25441542652105926
27011637692112527
28571732732119028
30351839778126429
32891994843137030
34862113894145231
36932238947153832
390923691002162833
413425061060172234
434326321113180935
458827801176191136
477528941224198937
503930541292209938
531332201362221339
559633911435233140


■誤り訂正レベルQの場合■
数字英数字漢字8bitバージョン
27167111
482912202
774720323
1116728464
1448737605
17810845746
20712553867
259157661088
312189801309
3642219315110
42725910917711
48929612520312
58035214924113
62137615925814
70342618029215
77547019832216
87653122436417
94857424339418
106364427244219
115970229748220
122474231450921
135882334856522
146889037661123
158896340766124
1718104144071525
1804109446275126
1933117249680527
2085126353486828
2181132255990829
2358142960498230
24731499634103031
26701618684111232
28051700719116833
29491787756122834
30811867790128335
32441966832135136
34172071876142337
35992181923149938
37912298972157939
399324201024166340


■誤り訂正レベルHの場合■
数字英数字漢字8bitバージョン
1710471
34208142
583515243
825021344
1066427445
1398436586
1549339647
20212252848
23514360989
2881747411910
3312008513711
3742279615512
42725910917713
46828312019414
53032113622015
60236515425016
67440817328017
74645219131018
81349320833819
91955723538220
96958724840321
105664027043922
110867228446123
122874431551124
128677933053525
142586436559326
150191038562527
158195840565828
1677101643069829
1782108045774230
1897115048679031
2022122651884232
2157130755389833
2301139459095834
2361143160598335
25241530647105136
26251591673109337
27351658701113938
29271774750121939
30571852784127340