たきこみの丸太

暇だった。

読めないQRコードを読んでみた。その3

Redditで読めないQRコードを見つけた。

解読できたので報告しようかと思ったら、ログインしても書き込み権限が無かった。しかも既に8か月前の投稿なので、今更感がすごい。が、ここの人たちは読めなかったっぽいので、読み方の解説だけでもまとめておく。

解読


既にここまでできてたのでこの画像から始める。ここまでの過程が正しいのかは確認してないが、まぁええやろ。
ここまで来てるのであればパディング領域がどこにあるかはわかる。

パディング領域には(EC11)16が入る決まりなので入れる。

これに誤り訂正処理をかけてみると完全復元できたのでこれで完了。

元のを作った人は文字数数え間違えてる気がする。インターリーブされてるから間違えやすい。

インターリーブ(分散配置)

QRコードでは8bitの情報を1ブロックとして扱うが、それが一塊として記述されるとは限らない。例えば1文字目"h"(01101000)2はココに書かれている。

なんでやねんという突っ込みを入れたくなるが、音楽CDでも使用されている書き方である。領域1と領域2が有り、どちらも15%の欠損が修復できる誤り訂正能力が有るとする。ある程度固まった場所にエラーが発生する事を想定すると、固めて領域を配置するよりもばらばらに配置した方が欠損領域を均等化できる確率が高いので修復もしやすい。
例えば領域を左右で配置したものとばらばらに配置したグリッドのまとまった部分を破壊してみる。

左の図では領域破壊率が偏っているが、右の図では分散されている様子が分かる。この状態は左の図では領域破壊率が17.5%と9.8%。右の図では13.9%と13.9%になっている。15%の誤り訂正能力が有るので、左の図は訂正できないが、右の図は訂正できる事が分かる。
処理は複雑になるが容量を増やさずに誤り訂正できる確率を高める良い作戦。

感想

読めないQRコードを探すといろいろ見つかりそう。まぁ、たくさん見つけたとしてもシステム化してボタン一つで読めるようなプログラムを構築している訳では無いので、見つけてもドット打ち作業が発生してメンドイから積極的に探す気は無い。たまにはやるかも?
システム化が可能か?でいうと困難。QRコードには種類が有りすぎて、QRコードが読めない原因は無数に存在する。どのパターンも良い感じに読めるようにするような処理は存在しないだろう。読み取り時間はかかるが通常より誤り訂正率がちょっと高いQRコードリーダーとかなら作れるかもしれんが。

読めないQRコードを読んでみた。 その2


前回このQRコードは読める。という話をしたが、右側が隠れているパターンも読めるのか?という疑問に挑んだ。
そして勝利したのでそのレポートを残す。

解読を始める前に

QRコードの左側には何が書いてあるのかを確認する。
主に
①必要なゴミ
②誤り訂正情報
③必要無いゴミ
の3ブロックに分かれている。

①必要なゴミ

Paddingと呼ばれる特に意味を持たない領域。
QRコードはフォーマットによって入力できる文字数に制限が有る。
このQRコードには53文字入れる事ができるが、36文字しか入っていない。その残り 53 - 36 = 17 文字が入るための場所。
厳密には全体領域440bitからモード情報(4bit)、文字数情報(8bit)、文字情報(36 * 8 = 288bit)を引いて
440 - 4 - 8 - 288 = 140bit が意味を持たない領域となる。
内容は(0 EC11 EC11 EC11 EC11 EC11 EC11 EC11 EC11 EC 0)16であり、(EC11)16が連打されているだけ。しかし無視は出来ない。誤り訂正の情報は上記全体領域(440bit)から作成されているので、誤り訂正を行う場合には持っておく必要が有る。

②誤り訂正情報

誤りを訂正するための領域。リードソロモン符号という理論によって誤りを訂正する。前回『同じ文字が3回書いてあったら』と書いたが実際に3回書かれているわけではない。

③必要ないゴミ

Remainderと呼ばれる特に意味を持たない領域。remainderは割り算の余りを意味する英単語。要するに余った領域。読み取り処理にて完全に無視される。
ここを何で埋めるかはQRコード作成ライブラリによって違いが有ったりするので、別のサイトで同じQRコード作っても同じものが出来なかったりする。

リードソロモン符号

データが破損していても訂正を可能とするためにデータに付加する情報。CDや衛星通信などにも利用されている。(誤り訂正によりCDは多少汚れていても音が飛んだりしないわけだが、今CDなんて聞く機会無いか。)
データを8bitずつのブロックとして管理し、リードソロモン符号自体も8bit単位のブロック複数個で構成される。
今回のQRコードはデータ領域が 440bit / 8 = 55ブロック
リードソロモン符号(誤り訂正領域)が 120bit / 8 = 15ブロック の計70ブロック構成で
2e + s ≦ 15
e : 誤りブロック数
s:消失ブロック(誤っている事が分かっているブロック)数
を満たすときに訂正が可能となる。今回eは使用しないので、単純に
『読めないブロックが15個以下なら訂正できる。16個以上なら訂正できない。』となる。(この計算上では1ブロック内の1bitが読めないのか、8bit全てが読めないのかは関係しない。)

QRコードを解析する

今回解読対象となるQRコードはこちら。

7%の誤り訂正が可能なQRコードが25%欠損しているため、QRコードリーダーでの読み取りは不可能。領域分割をしてみると文字数が確定しているので、必要なゴミ領域の3bitが確定する。

読める部分だけ読んでみると
ht���://yo����be/f��������3Q?t=3����
となる。36文字中19文字が読めていない。
ht���://
から始まるんだから、
https://
だろうという予想は可能だが、この3文字が確定しても次にやることに違いは無いので、この予想は使わずに進む。

破損ブロック数を数える

1Byte=1文字で、19文字読めていないのだから、1Byte=1ブロックで19ブロックの破損・・・ではない。誤り訂正に使用されるブロックは先頭から8bitずつ分割されていて、このQRコードの先頭には4bitのモード情報が入っているので、1文字と1ブロックはイコールではない。


この原理を踏まえて壊れているブロックを数えてみると20ブロックだった。15ブロックの訂正が可能な情報が20ブロック壊れているので、このままでは訂正不可能である事は分かる。

破損ブロックを確認する

誤り訂正処理を行うと15ブロックの誤りが訂正できるが、このまま実行しても失敗ログが出るだけで何の意味もない。20ブロック破損状態ではなく、15ブロック破損状態を作り出せれば誤り訂正処理が成功する。という事は5ブロックの情報が入力できれば意味のある誤り訂正処理は実行できる。
壊れているブロックを見てみると2bitしか壊れていないブロックが有ることがわかる。壊れているブロックの中で壊れているbit数が最も小さいブロック5つに注目する。

この5ブロックは 5 × 8 = 40bit 壊れているのではなく、17bitしか壊れていない事がわかる。この17bitが何なのかわかれば誤り訂正処理が可能となる。17bit2進数のパターンは 2 ^ 17 = 131072 なのでこの13万パターンの中のどれかが正解のビット列になる。

誤り訂正処理の実行

13万パターン全てに対して誤り訂正処理をかけてみる。13万という数字はループを考える時にそれほど大きな数字ではない。実際にこの13万回の誤り訂正処理にかかった時間は30秒程度だった。この処理速度なら 2^28 回(約2.68億回)ぐらいでも24時間かからない計算になる。
誤り訂正結果は512パターンで正常終了、その他は訂正失敗となった。正解のビット列は512パターンにまで絞られた。

文字定義という概念の導入

ByteモードのQRコードでは1Byteで1文字を表している。1Byteが表現可能なパターンは 2 ^ 8 = 256 個だが、この中でASCII文字として表現可能なパターンは100個程度しかない。つまりランダムな8bit列が存在したとき、それが文字表現できる確率は40%程度という事になる。だとすると誤り訂正により36Byteのデータが生成されて、それが全て文字として扱える8bitの集合となる確率はかなり低い事が想像できる。
(低そうというのはただの予測。一様分布では無いので、40%を36乗したような確率にはならない。)

文字数判定

512パターンの誤り訂正結果に対して、文字として表現可能な領域がいくつあるか確認してみると、36文字の表現が可能なのは1パターンのみだった。
131072パターン → 512パターン → 1パターン
でデータ確定。復号完了。
『https://youtu.be/f_djNpDqm3Q?t=3m22s』
右上欠損ではなく右下欠損パターンも同じ原理で複合ができる事を確認。

まとめ

・右側25%が欠損したQRコードでも手動で読み取りは可能。
・リードソロモン符号の誤り訂正限界を超えても誤り訂正を行う方法は有る。
今回リードソロモン符号の誤り訂正限界を超えるために『文字定義』を導入したが、使用したのは誤り訂正後の文字列に対してのみだった。この概念は誤り訂正前に入れる事もできるし、"https://"開始予想等の概念も導入すればさらに誤り訂正限界の向こう側に行ける。

感想

左側消失と比べると難易度が高かったが、やりたかった事は全部できた。さらなる拡張性も見えたが、解読対象となる題材を見つけてないので、次が有るかどうかは知らない。
今回流行りのChatGTPやらClaudeやらを多用してみて便利さをいろいろと実感した。プログラマーという職業の形がすぐに変わるとは考えにくいけど、プログラマー教育の分野ではもう人間がやる必要の無いレベルまで来ている。新人が「〇〇について教えてください。」と言う場合、プログラミングスクールの教師や会社の先輩より「AIに聞いた方が効率が良い。」
・・・あれ?20年前から「Googleに聞いた方が効率が良い。」って認識は有ったのに世界はそれほど変わってないか。やっぱGoogle以前・Google以降に比べたらAI以前・AI以降の世界変革は大きくないかもしれん。

QRコードが出るピクセルパズルを解いてみた。

前回QRコードの多様性について説いていたからか、この記事が私の心を貫いた。
これこそ私の求めていたQRコードの多様性そのものである。
aventador.blog.jp

ピクセルパズルをツール使って総当たりなんて方法で解いているなら、こっちは正しい人生の時間の消費方法ってのを示していきたい。

ピクセルパズルを書き写す。

順番に解いてく。

ここまで解けば答えがQRコードだと分かるので、QRコードの知識を使っても良いだろう。同一パターンが入る場所が2か所有るので、そのパターンを適用する。

固定パターンも配置する。

順調に来ていたが、この辺で一度手が止まる。

ピクセルパズルの特性上、複数回答が可能な場合が有る。現在の状態だと、パターンAでもパターンBでも答えに矛盾が出ない。

少々迷った後に、QRコードリーダーに読ませてみたら、どちらのパターンでも読み取りに成功してしまった。

もうできてたんかい。

こうして、人生の262,800分の1時間ほど無駄に消費された。

読めないQRコードを読んでみた。

マインクラフトのイベント時に撮ったスクリーンショットがこれだ。

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コードのデコード

細かい説明はメンドイのでこの辺のサイトでも見てほしい。
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%欠損パターンだったので、課題としてとっつきやすかった。右下もしくは右上欠損パターンの読み込みは難易度が上がるが、不可能では無い気がする。どこかで機会が有れば試すかもしれないが、既に満足しているのですぐにはやらない。

謝辞

・QRコード解説サイト様
QRコードを自力で読み取ってみる|Kaido

・Minecraft ガンギマリドラゴンサーバー様
#ガンギマリドラゴンサーバー

・ナゾナゾ仮面様

兎田ぺこらの仮説『壊れたネザーゲートから要塞は絶対に近い!!!説』は正しいのか?

先日の兎田ぺこらのマイクラ配信で以下の説が提唱されました。

【Minecraft】壊れたネザーゲートから要塞は絶対に近い!!!説。ぺこ!【ホロライブ/兎田ぺこら】
www.youtube.com

ネザー要塞の発見はマイクラRTAでも課題になったりするほど困難です。
確実な方法でなくとも、『こう探すと見つかる確率が高い。』などの指針を見つけるだけでも、大きな成果です。
この説の検証をしてみます。

検証

マイクラのシード値から特定オブジェクトの座標一覧を取得してくれるサイトが有るのでこちらを使用します。
Biome Finder - Minecraft App
※バージョンがJava 1.16 でホロサバのバージョンと異なりますが、今回検証に必要なオブジェクトの生成ルールは変更されていないようなので、問題は無いと思われます。

適当なシード値から『壊れたネザーゲート』の座標一覧を取得します。
f:id:takikomiprogramming:20210822162904p:plain
同一のシード値から『ネザー要塞』の座標一覧を取得します。
f:id:takikomiprogramming:20210822163821p:plain
今回使用したシード値は【-1490706610928362962】です。


この2つの座標系を合わせます。
ネザーの1ブロックは、オーバーワールドの8ブロックに相当します。厳密に計算すると他のルールも有りますが、細かいことは無視して、8:1に縮尺を変更した座標系を重ねてみます。
f:id:takikomiprogramming:20210822163200p:plain
右上にある茶色の四角形がネザー要塞、青い丸が壊れたネザーゲート、中央の赤丸が原点(0,0)です。
上記マップでは壊れたネザーゲートが40個以上有りますが、すぐにネザー要塞に行ける入口となるのは、そのうちの2つだけです。

データの評価

関連性は見つからない。
シード値をランダムで20個ほど検証してみたが、結果は変わらなかった。
壊れたネザーゲートもネザー要塞も、512×512ブロックのエリアに1つぐらいの頻度で発生している。座標系が8分の1である事を考えると、壊れたネザーゲートはネザー要塞の64倍有る事になる。

まとめ

兎田ぺこらが壊れたネザーゲートからの転移でネザー要塞を見つけるのは幸運兎の能力で有り、真似できるものではない。

兎田ぺこらロックマン2クリアタイム比較

時間比較グラフ

f:id:takikomiprogramming:20210712202544p:plain

時間配分グラフ

大空スバル
f:id:takikomiprogramming:20210505155620p:plain
兎田ぺこら
f:id:takikomiprogramming:20210712203242p:plain

時間一覧

大空スバル 兎田ぺこら
エアーマン 0:29:05 0:19:52
バブルマン 0:18:03 0:40:19
クラッシュマン 0:15:46 0:13:10
フラッシュマン 0:10:32 0:18:07
ヒートマン 0:48:20 0:42:22
メタルマン 0:23:18 0:24:45
クイックマン 0:50:32 0:31:35
ウッドマン 0:49:36 0:41:15
W1 メカドラゴン 1:25:34 0:26:58
W2 ピコピコくん 0:57:51 0:46:54
W3 ガッツタンク 0:26:48 0:29:21
W4 ブービームトラップ 2:39:01 2:06:15
W5 ボスラッシュ 2:18:30 1:59:59
W6 エイリアン 1:26:11 2:02:46
合計(時間) 13:19:07 11:43:38
合計(ババ) 3.33 2.93

桐生ココ帰還配信カウントダウン

このブログ開始のきっかけになった桐生ココがホロライブを卒業します。しかし、500年後に帰ってくる事を宣言されました。
卒業が2021年07月01日なので、帰還配信はおそらく2521年07月01日(火曜日)でしょう。





残念ながら私はこの配信を見れそうにありません。
が、きっとこの配信を見れる方々も沢山いることでしょう。


桐生ココ帰還配信が見れそうなホロメン

森 カリオペ/Mori Calliope
死神。年齢は分かりませんが、「私は生物よりも概念に近い存在。」という発言をしています。ホロメンの中で最も長く生き(?)そうです。
小鳥遊キアラ/Takanashi Kiara
不死鳥。死なないのではなく、死んでも記憶持越しで蘇れるそうです。何度蘇ったか、今何歳なのか、等は本人も覚えていませんが、500年ぐらい余裕でしょう。
潤羽るしあ
ネクロマンサー。自称1600歳なので500年後は2100歳。1600歳の状態でまだ学生なので、寿命は問題なさそうです。死者の魂と会話することも、死者を蘇らせることもできるので、彼女に頼んでおけば寿命が短いメンツも集まれる可能性が有ります。
がうる・ぐら/Gawr Gura
サメ。アトランティス時代生まれの9927歳。プロフィール上はホロメンの中で最高齢です。寿命は分かりませんが、500年は彼女の人生(サメ生?)の5%にすぎません。
雪花ラミィ
雪の一族(公式プロフィール)。1000歳越えのメンツと並べるとだいぶ年下の210歳。200歳を超えてから里を出て独り立ちした、と発言していましたので、10倍換算すると20歳で都会に出る、というそれっぽいイメージができます。500年後710歳の彼女は高齢者でしょうが、十分復帰配信の視聴が可能だと思われます。
クレイジー・オリー/Kureiji Ollie
ゾンビ。既に死んでいるので、『死んだから配信が見れない。』という事態は発生しません。が、かなり肉は腐っているようなので、体がどの程度の期間維持できるのかは分かりません。
兎田ぺこら
ぺこらんど星人。現在111歳(112歳?)。「111歳はまだ子供」という発言をしていますが、母親が222歳である、という発言もあります。これが正しいと、母親は111歳でぺこらを出産しているので、111歳は子供を産むような年齢、という事になります。そして、誕生日が来ることで年齢が増えるのか増えないのか問題も存在するため、寿命の推測は困難です。総合的にみると、500年後は困難な可能性が高いでしょう。
宝鐘マリン
海賊(自称)。現在17歳(2周目)なので、500年後は17歳(502周目)となるはずですが、宝鐘マリン78歳が別時空に存在していたため、年齢が増える可能性も存在しています。78歳時点で、そろそろお迎えが来る、という発言をしていましたので、通常通り年齢を重ねるのであれば、500年後の配信を視聴することは困難です。17歳で固定してくれる事を願います。
※『2周目』ではなく『2週目』という表記が正しい可能性有り。

総評

さびしい。