破れたQRコードでも読める理由:QRコードの構造と誤り訂正
QRコードの角の四角・タイミングパターン・形式情報の役割、バージョンと誤り訂正レベル(L・M・Q・H)で大きさが決まるしくみ、中央にロゴを入れても読める理由、余白の決まり、読み取る前の URL の確認をまとめました。
行きつけの定食屋のテーブルに貼られた注文用の QRコード。角がめくれたまま何か月も経ち、湯のみの跡まで付いています。それでもスマートフォンをかざせば、ちゃんとメニューが開きます。バーコードなら数本の線が消えただけで読めなくなるのに、QRコードはなぜ平気なのでしょうか。
理由は、QRコードに欠けた部分を復元するための予備の情報が最初から入っているからです。予備がどれくらいあり、どこが壊れてはいけないのかを知っておくと、QRコードを作るときの設定の意味がはっきりします。
読み取り機が最初に探すもの
3つの角にある大きな四角は**位置検出パターン(切り出しシンボル)**です。黒・白・黒・白・黒の幅が 1:1:3:1:1 になっていて、中心を通る線をどの向きに引いても同じ比率に見えます。そのため、カメラが斜めでもコードが逆さまに貼られていても、読み取り機は3つの角の位置と向きを先につかめます。4つ目の角に模様がないこと自体が、向きを知る手がかりです。
位置検出パターンの間には、白黒が交互に並ぶタイミングパターンが1行と1列通っています。定規のように、モジュール(マス)の間隔を教える役割です。バージョン2以上には右下寄りに小さな位置合わせパターンがあり、曲がったボトルや傾いた画面で生じるゆがみを補正します。最大のバージョン40には位置合わせパターンが46個も入っています。
位置検出パターンのすぐ横には、15ビットの形式情報が2か所に同じ内容で書かれています。誤り訂正レベルとマスクの番号がここに入っており、この情報自体にも誤り訂正の符号が付いています。読み取り機は、まずここを読まないと残りを解釈できません。
汚れても読める理由
残りのマスには、データとともにリード・ソロモン符号による誤り訂正の符号が入っています。CD や衛星通信でも使われている方式で、データの一部が消えたり読み間違えたりしても、予備の符号から元の値を計算して取り戻します。QRコードを作るときは、この予備をどれだけ持たせるかを4段階から選びます。
| レベル | 復元できる量(コード語単位、約) | 向いている場面 |
|---|---|---|
| L | 7% | 画面に表示するコードなど、きれいな環境 |
| M | 15% | 一般的な印刷物。多くの作成ツールの初期値 |
| Q | 25% | 工場や屋外など、汚れやすい場所 |
| H | 30% | 中央にロゴを入れるとき、傷みやすい場所 |
定食屋のシールが読めたのは、めくれや染みがこの範囲に収まっていたからです。ただし、この範囲はデータ領域の話です。3つの位置検出パターンのどれかが丸ごと消えたり、形式情報が2か所とも隠れたりすると、復元する前に読み取りに失敗します。
中央のロゴは「汚れ」として扱われる
お店のロゴが真ん中に入った QRコードが読めるのも、同じしくみです。読み取り機から見ればロゴは「壊れたマス」で、誤り訂正がその部分を補っています。ロゴを入れるならレベルを H に上げ、ロゴは 30% よりずっと小さくしておくのが安全です。印刷のにじみや傷も、同じ予備を分け合って使うからです。位置検出パターン、タイミングパターン、形式情報の上にはロゴを置きません。
大きさは中身とレベルで決まる
QRコードの大きさはバージョンで表します。バージョン1は 21×21 マスで、バージョンが1上がるごとに縦横4マスずつ増え、バージョン40は 177×177 マスになります。1辺のマスの数は 17 + 4 × バージョン です。
同じ文字数でも、どんな文字かによって必要なマスが変わります。QRコードには4つのモードがあります。
| モード | 入れられる文字 | 効率 | バージョン40-L の最大 |
|---|---|---|---|
| 数字 | 0–9 | 3桁で10ビット | 7,089 文字 |
| 英数字 | 0–9、A–Z(大文字)、空白、$ % * + - . / : |
2文字で11ビット | 4,296 文字 |
| 8ビットバイト | すべてのバイト(UTF-8 の文字列も) | 1バイトで8ビット | 2,953 バイト |
| 漢字 | Shift_JIS の漢字・かな | 1文字で13ビット | 1,817 文字 |
漢字モードがあるのは、QRコードが日本で生まれたからです。Shift_JIS の漢字やかなを1文字13ビットで詰められるので、日本語をバイトモード(UTF-8 なら1文字3バイト)で入れるよりずっとコンパクトになります。ただし、作成ツールや読み取りアプリによっては UTF-8 のバイトモードしか使わないものもあります。
実際の URL で計算すると、レベルの違いが大きさに直結するのが分かります。https://motitory.com/ja/tools/qr-code は37バイトです。初期値の M ならバージョン3(29×29)に収まりますが、ロゴを入れるために H に上げるとバージョン5(37×37)が必要になります。同じ印刷サイズならマスが小さくなるので、離れた場所から読むポスターほど URL を短くしたほうが有利です。
大文字で書いた URL が小さくなる場合
英数字モードには小文字がありません。そのため https://motitory.com(20バイト)はバイトモードで記録され、レベル M ではバージョン2が必要です。同じ URL を HTTPS://MOTITORY.COM と書けば英数字モードに入り、バージョン1(21×21)にちょうど収まります。URL の先頭部分(スキームとドメイン)は大文字・小文字を区別しないのでできる方法です。ただしパス(/ja/tools/…)はサーバーによって区別するので、むやみに変えてはいけません。
マスクは読みやすい模様を選ぶ工程
データをそのままマスに並べると、黒いマスが一か所に固まったり、位置検出パターンに似た模様が偶然できたりして、読み取り機が迷います。そこで作成ツールは決められた8種類のマスクパターンでマスを反転してみて、減点ルールに従って最もむらのない結果を選びます。どのマスクを使ったかは形式情報に書かれているので、読み取り機はもう一度反転して元のデータを取り出します。
余白を切り落とさない
QRコードの周りには、最低**4マス分の余白(クワイエットゾーン)**が必要です。レイアウトを整えるために余白をぎりぎりまで切ったり、柄のある背景に重ねたりすると、読み取り機はコードの境目を見つけられません。白い余白を十分に取り、明るい地に暗いマスで印刷するのが確実です。色を反転したコードを読めない読み取り機もあります。
読み取ったら、開く前に URL を見る
QRコードは人の目で中身を読めないため、悪用されることもあります。駐車場の精算機や公共の掲示物の上に偽の QRコードを貼り、決済情報をだまし取る手口が各国で報告されています。いわゆる「クイッシング(quishing)」です。上から貼り足したような跡があれば疑い、読み取った後は開く前にドメインが正しいかを確かめます。
作ってみる、読んでみる
QRコード作成では、URL や文字を入れて誤り訂正レベルを選び、QRコードを PNG や SVG で保存できます。同じ URL を L と H で作り比べると、マスの数が変わるのが分かります。手元の QRコードがどこにつながるかは、QRコード読み取りで開く前に確認できます。どちらも入力や画像は端末の中だけで処理します。
QRコードは1994年、デンソー(現在のデンソーウェーブ)が自動車部品の管理のために開発しました。特許を持ちながら権利を行使しないと表明したことで誰でも自由に使えるようになり、今では ISO/IEC 18004 として国際規格になっています(国内規格は JIS X 0510)。「QRコード」は株式会社デンソーウェーブの登録商標です。
参考
- ISO/IEC 18004:2015, Information technology — Automatic identification and data capture techniques — QR Code bar code symbology specification
- JIS X 0510「二次元コードシンボル-QRコード-基本仕様」
- デンソーウェーブ「QRコードドットコム」qrcode.com(歴史、誤り訂正レベル、バージョンごとの容量)