マインクラフトのイベント時に撮ったスクリーンショットがこれだ。4枚の画像を入手する事によってQRコードが完成してクイズの答えが分かる的なイベントだった訳だが、3枚手に入れた時点で気になってしまった。
『このQRコード読めるんじゃね?』と。
しかしこのままQRコードリーダーに読ませようとしても何の反応も無かった。
無理やり読む方法を模索してみる。
先に結論だけ言っとくと読めたよ。
最初のアプローチ
QRコードは誤り訂正機能を持っている為、多少欠損していても問題なく読み取れる。ある程度雑音を除去してやれば良いのでは?という考えでとりあえず全部手打ちして綺麗にしてみた。
で、ばっちりな場所にファインダパターン(左下のデカい■)を置いてみる。
しかし、いくらQRコードリーダーを傾けても反応しなかったのでデータを足していく。
縦タイミングパターン(本物)やら横タイミングパターン(適当)を入力したら読み取り失敗メッセージが出るようになったが、解読までは出来なかった。
このQRコードは29×29、バージョン3、誤り訂正レベルL(7%)である。
7%の欠損が復元可能なQRコードが25%欠損しているんだから、これで読めないのは当然と言えば当然の結果だった。
手動で読めば良いんじゃね?という考え
QRコード読み取りアプリを使ってみて読み取りが出来なかったんだから手動でやって読めるわけないじゃん。という考えが一般的だろうが、自分はそう思わなかった。QRコードの読み取りアプリは『何処のビットが間違っていて、何処のビットが正しいのか。』という情報を持っていない。しかし、このQRコードは、75%の正しい領域と左下25%の当てにならない領域で構成されている事が明らかなので、この前提を利用して手動で読めばQRコード読み取りアプリ性能以上の成果が出せると考えた。
誤り訂正とは?
『必ず同じ文字を3回連続で記述する。』というルールを作った時、”A”という情報を”AAA”として書き出す。読み込むときは逆に”AAA”を”A”に変換する。もし、読み込むタイミングで”ABA”という情報が存在した時、ルール違反になるわけだが、多数決によりAを正解とする事で、1文字の誤りを無かった事にできる。2文字の誤りが有ると情報の読み取りに失敗する。
これがとっても雑な誤り訂正の原理であり、QRコードにはこの考え方が入っている。
恣意的な誤り訂正
論理的に誤り訂正を行うと、多数決で勝たないと誤りを訂正する事が出来ないが、そもそも誤っている領域と正しい領域が明確に分かれているんだから、正しい領域だけを読めば誤り訂正用に付加された情報が全部なくても問題なく読めるはずである。
細かい説明はメンドイのでこの辺のサイトでも見てほしい。
QRコードを自力で読み取ってみる|Kaido
で、ごにょごにょするとこうなる。
フォーマット情報 | 111100010011101 |
マスクパターン | 011 |
データモード | 0100(8ビット) |
データ文字数 | 100100(36文字) |
この
QRコードに入っている情報が36文字(288ビット)だという事が分かった。もうこの時点で勝利を確信する。ダメだ、まだ笑うな。
8ビット毎に36文字を切り出して行く。
もう笑って良い。
QRコード領域の半分だけで全データの取得が出来た。後はバイナリを
文字コード表で文字にする。
『
https://youtu.be/f_djNpDqm3Q?t=3m22s』
36文字全部読めた完全勝利。
そして、この
QRコードは右半分さえあれば全データを読む事が可能だという事が分かる(マスクパターンが分からないので8回デコードする必要が有る?)。
まとめ
- アプリで読み取れないQRコードでも手動なら読み取る事が出来る。
- 左50%が欠損したQRコードでも読み取る事が出来る。
QRコードの『QR』は『Quick Response』の略であり、高速で読み取ることを目的としている為、欠損部分判定は余分な処理でしかない。しかしQRコードの使用方法が多様化してきたことによって、速度では無く誤り訂正レベルを重視したリーダーが有っても良いのかもしれない。QRコードはデータをマスク化しているが、暗号化しているわけでは無いので、特定条件で読み取られたく無い情報を作成するにはQRコードに入れるデータ側を工夫する必要が有る。
感想
非常に満足いく結果が得られた。この結論は今回使用したQRコードに対しての話なので、あらゆるQRコードに対する一般化された結論では無い事は認識しておいてほしい。QRコードサイズ、誤り訂正レベル、欠損箇所によって状況が変わる可能性が有る。特に今回のパターンは一番簡単な左下25%欠損パターンだったので、課題としてとっつきやすかった。右下もしくは右上欠損パターンの読み込みは難易度が上がるが、不可能では無い気がする。どこかで機会が有れば試すかもしれないが、既に満足しているのですぐにはやらない。