キャッシュレス決済の筆頭としてPayPayやLINE PayといったQRコード決済が日本においても普及し始めていますが、QRコードがどのように生成されているのかを知る機会は多くありません。「Creating a QR Code step by step」は、好きな文字列を表すQRコードを簡単に生成でき、さらにQRコードの生成過程まで理解できるウェブアプリです。

Creating a QR Code step by step

https://www.nayuki.io/page/creating-a-qr-code-step-by-step



まずは「Creating a QR Code step by step」にアクセス。ひとまずオプションの理解は置いておいて「Text string」に「GIGAZINE」と入力し、「Force minimum version」を「2」に設定して「Generate QR Code」をクリック。



生成されたQRコードがコレ。



ページを下にスクロールすると、QRコードの生成過程が説明されています。まず、ひとつひとつの文字に対し「どのエンコード方法が利用可能か」を判別。「NM」は数字モード、「AM」はアルファベットモード、「BM」はバイトモード、「KM」は漢字モードでエンコードが可能とのこと。



「GIGAZINE」の場合はアルファベットモードとバイトモードがすべての文字で利用でき、必要とするデータ量が少ないアルファベットモードが選択されています。



漢字や数字が混ざった文字列を入力した場合はこんな感じで、すべての文字に対応したバイトモードが選択されます。



続いて、それぞれの文字をビット列に変換。数字モードとアルファベットモードでは、連続する文字はまとめられた上でビット列に変換されます。



QRコードにはコードの一部が破損したり汚れたりしても問題なく読み取れるように「Low」「Medium」「Quartile」「High」の4レベルで誤り訂正機能を備えています。高レベルの誤り訂正ほど大きな破損に対応できますが、その分QRコードに保存できるデータそのもののサイズは減少する仕組み。

また、QRコードには40のバージョンがあり、バージョンが大きくなればなるほど白黒の「セル」の数が増加し、QRコードに保存できるデータの容量も増加します。QRコードに保存できるデータの容量は、バージョンと誤り訂正のレベルによって決まるというわけ。



「Creating a QR Code step by step」のQRコード作成画面で選択できた「Error correction level」と「Force minimum version」は、誤り訂正のレベルと最小バージョンを選択できるオプションです。



QRコードの元となるビット列は、以下のような構成とのこと。「Segment 0 mode」はエンコードモードを表し、「Segment 0 count」は文字数、「Segment 0 data」は入力した文字列のビット列が入り、余ったビットを0で埋めるパディングなどを行ってビット列を構築。



最後に誤り訂正のためのリード・ソロモン符号を追加して、QRコードとして表現するビット列が完成します。



いよいよコードの生成に入っていきます。QRコードにおける白黒のブロックひとつひとつは「セル」と呼ばれます。



まずは左上から6列目のセルと6行目のセルに「タイミングパターン」という、基準となるパターンを描画します。



続いてQRコードの特徴的な模様とも言える「位置検出パターン」と呼ばれる7×7セルのマークを左上、左下、右上に描画。



位置検出パターンを描画したら、「位置合わせパターン」を描画します。位置合わせパターンはQRコードの平面が曲がっていても正しく読み取れるように調整するためのパターンで、QRコードの大きさにあわせて個数が変化します。



位置検出パターンに沿って、フォーマットビットを仮描画しておきます。これでデータを格納するための準備が完了。



データを格納できる場所を探すため、右下のセルからジグザグにスキャンしていきます。



ジグザグスキャンで検出した描画されていないセルに対し、データを描画していきます。例えば16進数の「C5」は2進数で「11000101」であり、「黒黒白白白黒白黒」といった法則で描画されます。



続いて「マスクパターン」と呼ばれるパターンでQRコードを上書き。上書き演算は排他的論理和で行われるので、黒と黒が重なり合ったセルは白に変換されます。



このマスクパターンには8種類あり、QRコードを生成する画面で選択することが可能でした。



先ほど仮の状態で描画していたフォーマットビットをここで正しく描画します。



また、QRコードには「ペナルティパターン」と呼ばれるものが存在するとのこと。同じ色のセルが水平方向に5つ以上続いている場合はペナルティとなります。



垂直方向も水平方向の場合と同様です。5セル続いた場合は4ポイント、6セルの場合は5ポイント、7セルの場合は6ポイントのペナルティポイントが加算。



2×2セルの正方形が作れる場合もペナルティです。こちらは正方形1つにつき3ポイントのペナルティ。



垂直および水平方向に位置検出パターンに似たパターンがある場合もペナルティとなります。こちらは1パターンあたり40ポイントが加算されます。



また、黒セルの割合が45%〜55%の場合は0ポイント、0ポイントの範囲外で40%〜60%の場合は10ポイント、10ポイントの範囲外で35%〜65%の場合は20ポイントがペナルティポイントとして加算されるとのこと。

上記のペナルティポイントはマスクパターンの決定に使用されます。8種類あるマスクパターンのうち、最もペナルティポイントが低いパターンがQRコードの生成に利用されるというわけ。



なお、このアルゴリズムを用いたQRコード生成ソフトウェアも、Nayuki氏のGitHubに公開されています。

GitHub - nayuki/QR-Code-generator: High-quality QR Code generator library in Java, TypeScript/JavaScript, Python, C++, C, Rust.

https://github.com/nayuki/QR-Code-generator