QRコードの構造と破壊耐性について、基礎から応用まで段階的に学習できます。
QRコードは、一見すると単なるモザイク模様に見えますが、内部はきちんと役割の異なる領域で構成されています。
URL: https://hack.booth.pm/items/7517001
座標: -
図1: QRコードの構成要素をピクセル単位で色分け表示(下の要素にホバーでハイライト)
主要な構成要素
- 位置検出パターン(Finder) - 三隅にある大きな四角型のパターン。QRコードの位置と向きを特定します。
- タイミングパターン(Timing) - 縦横の細いシマ模様。モジュールの座標を決定します。
- Format情報 - 誤り訂正レベルとマスクパターンを格納します。バージョン7以上のバージョン情報は別領域です。
- Data + ECC領域 - 実際のデータを表すデータコードワードと、復元に使う誤り訂正コードワード(ECC)が規格所定の順序で配置されます。
これらの領域は、それぞれ異なる重要度を持ちます。特にFinderやTimingは「構造を支えるパーツ」として、 わずかな破損でも致命的な影響を与える可能性があります。
💡 注記: Data + ECC領域では、コードワードが複数ブロックに分割・インターリーブされて規格所定の順序で配置されるため、 本ツールではこれらを一つの「Data + ECC領域」として簡略化して表示しています。厳密な配置は、QRコードのバージョン(サイズ)と誤り訂正レベルによって異なります(詳しくは基礎2を参照してください)。
基礎1で、Data + ECC領域には「データコードワード」と「誤り訂正コードワード(ECC)」が配置されていることを学びました。 この誤り訂正の仕組みこそが、QRコードが一部破損しても読み取れる理由です。
QRコードには誤り訂正符号が組み込まれており、一部がかすれたり汚れたりしても自動的に復元できる仕組みがあります。 これは「リードソロモン符号」という技術に基づいています。
図2: 誤り訂正レベルごとのデータ量と復元能力の比較
誤り訂正レベル(ECC)
- Level L(Low) - 約7%の復元能力。データ容量を優先する場合に適しています。
- Level M(Medium) - 約15%の復元能力。バランスの取れた標準的な設定です。
- Level Q(Quartile) - 約25%の復元能力。やや汚れやすい環境向けです。
- Level H(High) - 約30%の復元能力。もっとも高い耐性を持ちますが、データ量は少なくなります。
トレードオフ:高いECCレベルほど多くのコードワード誤りを訂正できますが、その分、格納できるデータ量は減少します。「約7〜30%」は画像面積の破損率を保証する値ではありません。
Data + ECC領域の内部構成とインターリーブ
基礎1で言及した「Data + ECC領域」について、もう少し詳しく見てみましょう。 この領域は、実際には次の2つの要素が複雑に混ざり合っています:
- データコードワード - 実際のURL、テキスト、バイナリデータなど、読み取りたい情報そのもの
- 誤り訂正コードワード(ECC) - データが破損した際に復元するための冗長情報(上記のリードソロモン符号)
複数ブロックがある場合、同じ種類のコードワード同士をブロック間でインターリーブしてから、データコードワード群、誤り訂正コードワード群の順に並べます。 この分散とリード・ソロモン誤り訂正により、局所的な破損でも復元できる場合があります。ただし、復元可否は破損面積だけでは決まりません。
このインターリーブパターンは、QRコードのバージョン(サイズ/モジュール数)と上記の誤り訂正レベル(L/M/Q/H)の組み合わせによって決定されます。 例えば、バージョン1(21×21モジュール)とバージョン10(57×57モジュール)では配置パターンが異なり、 同じバージョンでもECCレベルLとHでは配置が変わります。
このように、厳密な可視化は非常に複雑になるため、本ツールでは教育目的として、Data + ECCを一つのオレンジ色の領域としてシンプルに表現しています。
※ 本ツールではjsQRライブラリの制限により、ECCレベルを直接取得できないため「不明」と表示されます。
基礎1で学んだ構成要素に加えて、バージョン2以上のQRコードにはアライメントパターン(Alignment Pattern)という追加の構造要素が存在します。
図3: QRコードのバージョンによるアライメントパターンの配置
アライメントパターンとは
アライメントパターンは、QRコードの内部に配置される小さな同心円状のマークです。 Finderパターンが「QRコード全体の位置と向き」を特定するのに対し、アライメントパターンは「内部の歪み補正」を担当します。
バージョンによる配置の違い
- バージョン1(21×21モジュール) - アライメントパターンは存在しません。サイズが小さいため、Finderだけで十分な精度が得られます。
- バージョン2~6(25×25~41×41モジュール) - 1個のアライメントパターンが右下付近に配置されます。
- バージョン7以上(45×45モジュール~) - QRコードが大きくなるほど、複数個のアライメントパターンがグリッド状に配置されます(バージョン7では6個、最大バージョン40では46個)。
役割と重要性
アライメントパターンは、次のような状況で重要な役割を果たします:
- 物理的な歪み - 印刷された紙が曲がっている、シールが貼られた表面が湾曲しているなど
- 撮影時の角度 - カメラがQRコードを斜めから撮影した場合の透視歪み
- 大型QRコード - サイズが大きいほど、端と中心で歪みの影響が異なるため、内部の基準点が必要
図1のQRコードを見ると、これはバージョン3(29×29モジュール)であり、 右下付近に1個のアライメントパターンが配置されているはずです。ただし、Data + ECC領域として簡略表示しているため、この図では明示していません。
💡 クラッシュテストでの意味: アライメントパターンもFinderと同様に構造を支える要素なので、 ここが破損すると大型QRコードでは読み取り精度が低下します。特にバージョン7以上の大型QRで実験する際は、アライメント付近のダメージにも注目してみてください。
QRCrashTestでは、QRコードの各領域をモデル化し、どこが壊れると致命的になりやすいかを可視化しています。
図4: 致命度ヒートマップ(赤→黄の順に危険度が高い)
致命度の違い
- Finder・Timing(高致命度) - これらが破壊されると、わずかなダメージでも読み取り不能に直結します。
- Format情報(中致命度) - メタ情報の破損により、デコードアルゴリズムが混乱します。
- Data領域(低〜中致命度) - 誤り訂正によってある程度の欠損が補われるため、同じ面積でも致命度は相対的に低くなります。
解析タブの「致命度ヒートマップ」を有効にすると、どの領域が「当たりどころが悪い」かを視覚的に確認できます。
図5: 典型的なダメージパターンと読み取り結果の例
このツールで確認できること
- Finder付近の脆弱性 - 少し塗りつぶすだけで、読み取り不能になりやすいことを体験できます。
- Data領域の耐性 - 散発的な汚れがあっても、意外と復元されてしまうことを確認できます。
- ダメージ形状の影響 - 影やかすれの形状・位置によって、致命度が大きく変わることを観察できます。
- 破損率と読み取り可否 - この画像とjsQRの組み合わせで、破損位置による結果の違いを観察できます。
推奨される実験手順
- プリセット攻撃を試す - 「攻撃シナリオプリセット」で典型的なダメージパターンを試してみましょう。
- Finderを攻撃 - 左上のFinder領域を少しずつ塗りつぶし、どの時点で読み取り不可になるか観察します。
- Data領域を攻撃 - 中央のData領域に汚れを散布し、誤り訂正の限界を探ります。
- 複合攻撃 - Finderへの小ダメージ + Data領域への分散ダメージを組み合わせて閾値を探ります。