ここ数日QRコードを利用した某決済サービスが世間を騒がせていますが、いかがお過ごしでしょうか。

URLをはじめ様々な情報を伝えるために使われるようになったQRコードですが、 どのように情報が書き込まれているか知っている人は意外と少ないのではないでしょうか。

この記事では、QRコードやその他バーコードのライブラリ「zxing」をGoへ移植した過程で知った、 QRコードに関するあれこれを紹介したいと思います。

QRコードとは

QRコードの歴史については、QRコードの発明元でもあるデンソーウェーブのサイトをぜひご覧ください。

QRコードの規格は日本工業規格(JIS X 0510)だけでなく国際規格(ISO/IEC 18004)にもなっていますし、 デンソーウェーブのサイトにもあるように自由に利用できます。 そもそも主要な特許は出願から20年を過ぎて期限が切れています。

ひとつ気をつけないといけないのは、「QRコード」の商標権は現在もデンソーウェーブが持っていますので、 似ているけれど異なる2次元コードを「QRコード」と呼ぶのはご法度です。 この間違った呼び方を本当によく見かけるのでみなさん気をつけてください。

QRコードに見られる工夫

「QR」が「Quick Response」に由来しているように、素早い読み取りのための様々な工夫がみられます。

検出のための工夫

まずは3つの隅にある四角形、「位置検出パターン」です。 QRコードリーダーはまず、「黒1:白1:黒3:白1:黒1」という比率の四角形を3つ検出します。 見た目にもわかりやすいですし、素早く検出できます。

3つのパターンの位置関係から歪み補正をすることができるため、カメラが正面から少し傾いていても正確に読み取ることができます。 さらにドット数の多いQRコードでは、規定の位置に小さい四角の「位置合わせパターン」が置かれるので、 より正確な補正もできます。多少歪んだ画像でも問題なく読み取れるので、何度も撮りなおす必要がなくなります。

読み取りミスを減らすための工夫

読み取りミスを減らすことで、撮り直し回数を減らすことができます。

一般的に同じ色が長く連続していると、何個分なのかわかりにくくなり読み取りエラーが増えます。 また、黒1:白1:黒3:白1:黒1の位置検出パターンと同じ比率のパターンが現れてしまうと、位置検出を邪魔してしまいます。 QRコードではこのようなパターンを避けるために、規定の8種類のマスクから適したものを選んでXORすることになっています。 たまに最適でないマスクを選んでしまっているQRコードを見かけることもありますが、普通は問題なく読み取れます。

さらに、格納されるデータはエラー訂正符号(リード・ソロモン符号)が付加されています。 この符号は、一部分が削れたといったバーストエラーに強いという性質があり、他の2次元バーコードでもよく使われています。 QRコードでは、最大で30%程度欠損してもエラー訂正できるようになっています。

こういった工夫によって高速で確実な読み取りができるようになっています。

余談ですが、よく見かけるQRコードの中にロゴや文字が入ったものも問題なく読み取れるのは、このエラー訂正符号のおかげです。 逆に言えばその分エラー訂正能力を下げてしまうことになるので、あまりおすすめできない使い方です。

QRコードに入れられるデータ

QRコードには格納するデータの種類ごとに「モード」があり、モードを切り替えながらデータを格納するようになっています。 基本的にはテキストデータですが、どんなバイト列でも入れられる「8ビットバイトモード」があるため、原理的には何でも入れられます。

ここでは代表的なモードについて紹介したいと思います。

数字モード

1-9の数字文字列を格納するモードです。 3文字を10ビットで表現するので大変効率が良いです。 数字以外を入れるには他モードに切り替える必要があります。

英数字モード

数字(0-9)、英大文字(A-Z)、スペース、記号8種($%*+-./:)の45種類の文字を格納するモードです。 2文字ずつを11ビットで表現するので、なかなか効率が良いです。 残念ながらURLを表すには文字が足りません。

8ビットバイトモード

バイナリデータをそのまま格納するモードです。 JISやISOで規定されるデフォルトの文字コードはJIS8なのですが、守っていない実装を時々見かけます。 「拡張チャネル解釈モード」によって文字コードを指定することができるので、非ASCIIな文字を入れる場合は必ず指定すべきです。

URLを格納するには、この格納効率が最も悪いモードを使うしかありません。 もったいないですね。

漢字モード

QRコードが日本生まれということもあってか、Shift_JISの2バイト文字を格納する専用モードがあり、ISOにも含まれています。 13ビットで1文字を表現することができます。ちょっとだけ格納効率が良いです。

汉字モード

これはJISやISOには含まれていませんが、中国の国家規格(GB/T 18284)で規定されているモードです。 簡体字の文字コード(GB-2312)の2バイト文字を、漢字モードと同様に1文字13ビットで表現します。

この他にもハングル文字を格納するモードがあるらしいのですが、規格文書を見たことがないので詳細はわかりません。 情報をお持ちの方はご連絡ください。

おわりに

いかがでしたでしょうか。 QRコードの知られざる一面が垣間見れたのではないでしょうか。

こんなの知ってたよ、常識だよという方はぜひ、ZXingの移植作業を手伝ってください。 よろしくお願いします。

(画像出典:JIS X 0510)