ログ: 2009/10

進まず焦らず

2009/10/23 | ごみ | コメント (1)

放置気味ですが生きてますがいまいち時間がない.

最近あったことリストでお茶を濁すと:

  • 日本人の開発責任者さんが書いたよというから 入門 Git で Git 入門した*1ら各コミットの構成を考えるのに git 管理下でやってる開発本体と同じくらい時間をかけるようになったアホか.
    偏執狂の人が気持ちよく効率よく使うためのガイドラインどこかにないですか!
  • 生協でオライリー 15% off とかやっていたのでプログラミング Perl と JavaScript 第 5 版と UNIX システム管理 第 3 版あたりを揃えた.後悔はしていないがこういう本は会社やら研究室やらの経費で揃えてもらうに限ると思う
  • 逃げ続けてきた C++ にまじめに取り組みつつある.逃げてる間に色々な言語をかじったおかげで,複数の言語の集合体として認識すれば理解しやすいという説明でしっくり来たりしてまあ今度こそなんとかなれと思っている
  • 地球を学んでいるけれど経度と緯度どちらがどちらかわからず失笑を買う常識のない東大生そのものとなる
  • iPhone がまったく有効活用されていないのでなんとかしたいと思いつつ手に取るとフリック入力タイピングを始めるばかりで何も進まない
  • ほとんどの口座が空なので(使い分けを意図して)口座が複数ある意味がまったくない
  • クロノクロスをやっている*2
  • 近所のスーパーのおもちゃ屋のカードダスのレアカードが定員により抜かれている疑惑が濃厚で萎える
  • アクセス解析を見て wotaku >> gohan の構図が依然健在であることを直視し萎える
  • こういう一行でまとめられる内容は Twitter でやればいいとわかりつつも post する気にならない

ゲーム書いたり文章書いたりしたい.クリエイティビティ(笑)とかにすがらないと生きていけない状況ではある.

  1. 入門といいつつ,実装から理解しようって流れが大半で吹いた.でもとても面白い. []
  2. 実はクリアしたことない. []

とぅるーたいぱー(笑)

TWOR@qwe すべキー XF

今さらだがすべキーの更新で達成.

ぁゃιぃことをしている真っ最中に更新するという極めてうさんくさいことになってしまったが実際出せてしまったものはしょうがないというかなんというか.こそこそ隠すのも変な話だし.

それにしてもトゥルータイパーである*1

すべキー XF って条件だけ他*2と比べて異様に難易度高いと思うのは俺だけではないはず. いやすべキー XF とかちょっと打ちさえすればゆとりですよ,とオリジナル打てる人に言わせればもちろんそれはその通りなんだろうけど,達成している人数という客観的なデータもあるし,心理的なものを考慮に入れればやはり異様に難易度高いと言い切れる.だからどうというわけでもないけど.

あえて称号らしきものを狙うとすれば次は Z タイパーかな. 実はまだ TWJR@qwe 総合 XX だからね.

  1. みたいな言い回しが若干イラっとくるこの頃である. []
  2. JR もしくは JK で基本常用語 XF ,かつ EW 基本 1500 語で XF. []

たまには打つ

e-typing 秋の言葉 618pt

e-typing 秋の言葉.

メンタル逆ギプスのために yaet では 500 kpm ~ 650 kpm でフェードアウトするように設定して打ってた(半年くらい前)んだけど,秋の言葉って割と消せるイメージがあったので頑張った.

スクリーンショットの 「サンマ~」 から 「焼き芋~」 まで超加速で来ていて 「いしやーきいもー」 で不意を突かれて死にかけ 「文化祭」 で実際に死んだ*1

たまにはミスで泣く.

  1. ここで 3 ミス. []

TWOR 解析 (2)

2009/10/11 | ごみ | コメント (6)

前回の続き.

http://dvorak.jp/archive/twor_subekey_sample.zip (9.5 MiB)

今回は,前回得た上記の一次元のサンプリングデータから何がわかるか*1調べてみよう,というようなことをやってみる.

いきなりものものしいアルゴリズムで始めるのもなんなので,手始めに各 1 文字の出現頻度を調べてみる.「特に頻出の文字」 「頻度が少ない文字」 などが存在するかしないかが調べられることになる.

twor1.py とかこういうのを書いて実行:

  : 1200046
! : 199954
" : 199460
# : 200069
$ : 199927
% : 199931
& : 199930
' : 200294
( : 199659
) : 200283
* : 199927
+ : 199899
, : 200310
- : 199874
. : 199737
/ : 200209
0 : 199993
1 : 199899
2 : 200050
3 : 199829
4 : 200182
5 : 200006
6 : 200281
7 : 199667
8 : 200237
9 : 199911
: : 199861
; : 199832
< : 200267
= : 199679
> : 200304
? : 200360
@ : 199668
A : 199954
B : 200003
C : 199883
D : 200087
E : 199996
F : 199927
G : 200400
H : 200056
I : 200023
J : 200288
K : 200199
L : 199780
M : 200053
N : 200065
O : 199758
P : 200170
Q : 200037
R : 200035
S : 199964
T : 200514
U : 199946
V : 200023
W : 200192
X : 199963
Y : 199992
Z : 200273
[ : 200189
¥ : 200251
] : 199424
^ : 200156
_ : 199728
` : 199701
a : 199627
b : 200106
c : 199833
d : 199730
e : 200364
f : 200088
g : 199896
h : 200362
i : 199858
j : 199859
k : 200213
l : 199734
m : 199618
n : 200157
o : 199661
p : 199895
q : 200209
r : 199978
s : 200187
t : 199971
u : 199870
v : 200162
w : 200104
x : 199982
y : 200081
z : 199733
{ : 200160
| : 199946
} : 199874
~ : 200177

直感的に以下のふたつのことが推測できる*2

  • ほとんどの文字の出現頻度は同じ
  • スペースの出現頻度は,他の文字の 6 倍

文字単位で見るとスペース除けば全て同じ頻度っていうのは,意外性がないというか,完全ランダムならそうだろうし常識的にそうだろうなっていう気がしますが,もうちょっと後の考察を踏まえると再び意味を持つかなと思うので,一応押さえておきたいポイント.

スペースの頻度が他の文字の 6 倍(きれいな倍数)というのは素直に面白い結果. これだけ見ても,出題文字列は単なるランダムではなくある程度考えられたロジックに基づくものなんじゃないかなぁという香りはしてくる.

今度は文字単位ではなくて, 隣り合った 2 文字をセットにして,2 文字セットの出現頻度を見てみよう*3. たとえば 「ab」 と 「ac」 では頻度が異なるだろうか? とかいう話ね.

先ほどのスクリプトを手直しして,n 文字セットでカウントできるようにする(twor2.py). 出力を使いやすいように,区切り文字はタブ文字に変えた.

n = 2 とした結果の抜粋 (全体は若干サイズあるのでリンク):

aa  2389
ab  2990
ac  663
ad  3432
ae  844
af  2257
ag  3465
ah  663
ai  4425
aj  1388
ak  2179
al  4743
am  389
an  5731
ao  2296
ap  2034
aq  6466
ar  429
as  6337
at  3326
au  2318
av  7572
aw  811
ax  6494
ay  4588
az  2299
a{  209
a|  51
a}  183
a~  27

ということで,2 文字にしてめでたく偏った. 先に文字単位の頻度は等しいことを確認しているので,「av」は 7572 回あって,「a~」は 27 回しかないという 100 倍オーバーの差は,有意とかそういうレベルではない*4明々白々たる偏りである.

この時点で

  • 一文字単位で都度ランダムに取ってきた文字を並べているわけではない
  • 頻出の文字列パターンがどうやら存在する

ことが言える.第一目標は達成した*5

次に気になるのは当然パターンそのものがどうなっているのか.

といってもいきなりその詳細は調べようがないので,各文字列長 n についてもっとも頻度が高い一団を抽出し,そこから法則が推測できないかとやってみる.

すなわち頻度を調べる文字列長を n = 3, 4, 5, 6 と大きくしていく.ただ,さっきまで使ってた馬鹿アルゴリズムでカウントするのは効率的にアレなので,ここらでインデクスを作っておくような賢いアルゴリズムを使うことにする.

自分で実装は面倒なので SUFARY を使った. 先に mkary でインデクスを作っておけば,

sang -n 6 -t 1000 out2.txt

とすることで長さ 6 文字の部分文字列のうち 1000 回以上出現したものがそれなりに高速に出力される,とかそんな感じ(-t 指定しなければ全部出る).

これを利用して調査したところ,

となった.

これはまた色々なヒントが隠された結果に思える.

まず,6 文字とかいう割と長い設定でも, 10 万回に 1000 回以上出現しているパターンが 100 オーバー見つかったということ.これは練習したりする上で実用に耐えるレベルのパターンだ.

そして,n 文字から n+1 文字へと一文字増える毎に約 2/3 とかそれくらいに最頻出の一団の頻度が減っているわけだけど,n+1 文字目には均等に文字が出てくると仮定した場合にはこれは 1/95 になるはず*7なので, 2/3 という減り方は超ゆるやか.ちなみに,ここには載せなかったが n = 8 とか n = 9 でもいきなり 1/95 になることはなかった.それ以上になるとサンプル数が十分でなく,S/N 比が小さくなってくるので参考にならないが.

感覚的には明らかだけど一応ついでに書くと,n+1 文字のパターンは n 文字のパターンに新たな 1 文字を付け加えたものになっている.ただし,n 文字のパターン全てに,対応する n+1 文字のパターンが存在するわけではない.

このことから,以下のことが推測できる:

  • 長さの決まったパターンの基本単位のようなものは無い
     (少なくとも長さ 9 以下ではありえない)
  • パターンの元(ソース文字列)があるとすればそれは十分に長く,その部分が実際の頻出パターンとして表れている

さらにこれは根拠のない話だけど,一文字ごとに約 1/3 の確率でソース文字列からの転写の継続をやめ,別のパターン(ソースの別の位置?)に飛ぶというような処理を考えれば,上記のように最頻出のパターンの出現数が減ることに説明がつくかも.

この辺りになるとまだ俺もあんまり確信していることは多くなくて*8,推測とかばかりになってきて申し訳ないが,ここで特筆に値するポイントがある.

twor6_out.txt を見て,眺めてみて何か感じないだろうか.

わかりやすそうなところを貼ると

1091 AQt%Aa
1058 BRu&Bb
1107 CSv'Cc
1023 DTw(Dd
1069 EUx)Ee
1088 FVy*Ff
1029 GWz+Gg
1091 HX0,Hh
1011 IY1-Ii

もう分かったと思うのでもったいぶらずにいけば,文字列の各文字をアルファベット順に「ずらす」*9と次のパターンの文字列になっている.

  • 文字を「ずらす」操作がなんらかの法則に従って行われている

ことが推測される.そして,そうして「ずらす」ことによって作れるパターン群をまとめて(オリジナルパターンとでも呼ぶか) 1 つとして数えると,

  • 6 文字の最頻出オリジナルパターンは 2 種類
  • 5 文字では 3 種類
  • 4 文字でも 3 種類
  • 3 文字では 4-5 種類

等と,その数が激減する.このことを踏まえて,「ずらして作れる文字列」を同一視して改めて初めから調べてみると何かわかるかもしれない*10

要素の列挙になっていて本質的な解析が全然進んでいないという話はあって,これらの情報を統合できるのかどうか甚だ怪しいんですが,まあヒントは少ないより多い方がいいに決まっている.

さらにもう一点(One more thing…).

今まで部分文字列に注目してきたけど,ちょっと視点を変えて,out2.txt をそのままソートしてみたらどうなるだろうか,とやってみた.
twor_subekey_sample_sorted.zip

適当に切り出してきた一部分はこんな感じ:

]a0{=f&.Pjp7Ko4[Ft*( yt  38;d7.DY#{_S(#NN#)_n(¥Ni-A c<-XXr`HSwEg10;Rv5~qq!Ial&XL++ k&/MU9>bt4]Cey|Q3] fn=Au#.FVx)Kk-#Pz7 TZ[ Yo'`d3~@i);Tns!Nr7^Iw-+C1w  6">g";Gb&~|W+&QQ:?A0? Zu]MKp|^jj3BUe8Qt$$|d8)G2
]a0{=f&.PjpAKo4[Ft*J y] j38;d7.DY#{_S(#NN-< w< Wr@JHm_@gg~ Q' Nq!Cca5HDzz*Rku/g9>>Ht/]W)*|l3$ 0nAAa# Fpx{K4-[Oe6<Tt@OY8'Jd.~Dix: m#D~r<^cw1MX1' R6@WM hp?CHZ/GWy*Llj$QL88Vas ap({e42¥je<<ot"Ot8_Jx.,E2x 
]a0{=f&.Pkp7Ko4[Ft*( yt  38;d7.DY#{_T(#NN-< w< Wr@JHm_@gg0 Qb5Nq!!_a5&Dzz*Rku/gU>>Ht/]We*|l3$ Ln8Aa# Fpx{K4-[FVy*Ff)8Lw4 LR/^Rh!@Rr?+X8'JXdv dt- d31[jf=>jp7Lq5]Hp&$ wr}~v1*X2) T1<:J83EFT$[ Z?KfZz{Vf&Q
]a0{=f&.PkpAKo4[Ft*J y] j38;d7.DY#{_T(#NN-< w< Wr@JHm_@gg~ Q' Nq!Dca5HDzz*Rku/g9>>Ht/]W)*|l3$ 0nAAa# Fpx{K4-[Pe6<Tt@OY8'J<Zr1[ bw_O1r~dl; D!,DSv&Ih+!Mw4 RXp}Wm%]b0y>gb./kq8Lp5¥Gu+(Azu  39<e8/EZ$|`T)$O
]a0{=f&.Qkp7Ko4[Ft*( yt  38;d8.DY#{_T(#NN-< w< Wr@JHm_@gg0 Qb5Nq!!_a5&Dzz+Sku/gU>>Ht/]We*|l3$ Ln8Aa# Fpx{K4-[Pe6<Tt@-Y8'Jdi~Eix; n#D~r<^c/?Az> Zt]LJo|]ij BT)AQs$Ffc7KF12OUm`Tj"[Yyw;dY,,~n5' 2?DDc& Hr}
]a0{=f&.Qkp7Ko4[Ft*( yt  38;d8.DY#{_T(#NN-< x< Xr@JHm_[gg0 Rb5Nq!!_a5&Dz0+Sku/hU>>Ht/]We*|l3$ Ln8Aa# Fpx{K4-[$=Id( iY-KS7<[r2[ cw`O1r~dl; EW,DSv&Ihf!MI45RXp}Wm%]b1y>gb./kq8Lp5¥Gu+(Azu  P9<{U/EZYy`Td$O
]a0{=f&.QkpAKo4[Ft*J y] j38;d7.DY#{_T(#NN-< w< Wr@JHm_@gg~ Q' Nq!Dca5HDzz*Sku/g9>>Ht/]W)*|l3$ 0nAAa# Fpx{K4-[Pe6<Tt@OY8'Jd.~Eix; m#D~r<^cw1MX1' R6@WM! Gv&,|q+_Qk:CAf?:Za]}K9|Hj4 WTyB tt39<e8/EZ$|`T)$O
]a0{=f&.QkpAKo4[Ft*J y] j38;d8.DY#{_T(#NN-< x< Xr@JHm_[gg~ R' Nq!Dca5HDz0+Sku/h9>>Ht/]W)*|l3$ 0nBAa# Fpx{K4-[Pe6<Tt[OY8'Jd.~Eix; n#D~r<^cw2MX1' R6@WM! Gv&,|q+_Qk:DAf?:Za]}K9|Hj4 WTyB ttGLd=Ka2.Ppn(UP#
]a0{>f&.Qkp7Kp4[Ft*(Ayt  38;e8.EY${_T($NNYdw ds,~i75_mi?@Dx&:H#}MMm/HR1BCW'] b@)gf5 ak+=Vp^FPu9`Ky/Pt3| o8GYj$=Jd) iY-KS7<¥r2[Acw`O1r dl; EW,DTv'Iif!NI45RXp}Wm%^b1z>gb//lq8Lp5¥Gu+)Azu  P9<{U/EZZy`Ud$O
]a0{>f&.Qkp7Lp4¥Fu*(Ayu  38<e8.EY${_T($NO-= x< Xr[KHm`[gh1 Rb6Oq"!_a5&D00+Sku:hU?>Hu/]We*|l3% Lo8Ba$ Fpx{K4-¥Pe7<Ut[-Z8'Jdj~Eiy; n$D~s=^cw2+X1( S6[>M"6HH',|q+_Ql:DBf?:aa^}K9}Hj4 WUzB tt$Ldo)a2..Bn)=P#
]a0{>f&.Qkp7Lp4¥Fu*(Ayu  38<e8.EY${_T($NO-= x< Xr[KHm`[gh1 Rb6Oq"!_a5&D00+Sku:hU?>Hu/]We*|l3% Lo8Ba$ Fpx{K4-¥Pe7<Ut[-Z8'Jdj~Eiy; n$D~s=^cw2+X1( S6[>M"6HH',|q+_Ql:DBf?:aa^}K9}Hj4 WUzB tt$Ldo)a2..Bn)e$O

こんな大きなヒントを今まで見逃していたとは. これは決して OCR で読み込むときに同じ回を二度記録してしまったとかいうものではない*11.また文字列長は 200 だから,たった 10 万回の試行でたまたま同じようなものが出ましたとかいう偶然でもありえない.すなわち,全体としてこれだけ似ているワードが出題されることがあるのだ.

何より注目するべきは,途中はもちろん最後の方に至るまで(数パターンはあるけども)類似性が見られること.ここから,文字列を生成している途中に乱数に応じてまったく違うパターンに遷移して戻ってこないということはあまりなさそうで,初期値がまずあって,その初期値が何らかの形で後々にも再利用されるようなロジックであることが推測される.

これまでのヒントと合わせてまた根拠無く考えれば,長大なソース文字列のどの地点から読み始めるかを乱数で決定し(初期値),順次そこから読んで出題文字列として採用していくが,その都度ある確率で文字をずらしたり,別の場所から x 文字読み出して代用するような処理が挟まることがある……というような処理を書けばこのような結果が得られる気がする.十分条件のひとつに過ぎないけど.

まあとにかく

  • 出題文字列の生成においては,初期値依存性がとても高い

ことは確か.

というわけで,調べたり無いところもあるが,基本的性質いくつかが示され,頻出パターンといってもいいものの存在が確信でき,さらに,役立ちそうなヒントがたくさん見つかった. まだこれらをつなぎあわせるには至っていないが,何歩かは進めた気がする.

# それにしても,今回出てきたことのほとんど全てを経験的に見抜いていたとりのさんがすごすぎる

次回予告

TWOR を取り巻くオカルトじみた噂. 「時間帯によってワードの傾向が変わる」.

多くのタイパーがそのことを示唆し,表舞台を去っていった.

時を刻まない時計,二次元サンプリングデータは,その詳細を解き明かすことができるのか.

次回 「静止した時の中で」 

この次も,サービスしちゃうわよ!

  1. わざわざこのように断る理由は,エントリ末尾次回予告にあるように時間を考慮にいれる必要性を感じるから. []
  2. 暇なら標本分散計算するなどして検証するべき. []
  3. 要するに N-gram 分解の頻度チェックをやっている. []
  4. 本当は検定ry []
  5. なんも証明してないけど. []
  6. 4000 とか 5000 とかある子は,スペースを含んでいる.スペースは先に調べたとおり頻度が 6 倍であるのでその影響と考えられる.一旦無視. []
  7. すべキーの文字種は 95. []
  8. 試行錯誤しながらエントリ書いてる段階だ. []
  9. ちゃんと言えば ascii code を +1 する. []
  10. まだやってない.方法としてはある文字と次の文字の文字コードの差を取ったデータを解析すればいいと思う.興味湧いた方はチャレンジして情報公開してくれると俺が楽できて助かりますので遠慮なくどうぞ. []
  11. 元々のサンプルデータでは隣り合ってないし. []

信じられないことに第 8 学期

2009/10/10 | ごみ | コメント (3)

ブログのペース落ち気味ですがお察し下さい.再びリアルがアレでね.懲りないもので.

雰囲気を見る限りしばらく平日にまとまったエントリを投下できることが少なくなる(かも).

そして無駄口は他所で叩くことにしたので,このブログにはまとまったエントリしか投下されない(かも).

やめますとか言うことは間違ってもないけどね.色々と. 宣言してもしなくてもどうせやめないんだし,何ごともなかったかのように続きます.

ご心配なく. 週に三日はいつも通り. 多分.

第二審無罪

例の金子氏の裁判

これはリアルに応援せざるをえなかった数少ない話だったので割と本当に嬉しい.freekaneko に当時の身分としては大きな金額を突っ込んだりしていたので,他人事ながら当事者的な喜びがあったりもする*1.裁判ってアホほど時間がかかるもんだなということも実感できた.

まあ俺の場合は個人的な愛着みたいなものが含まれているけど,そうでなくても,若干怪しげなものを無責任に書いたり書かなかったりする人間にとって,とてもありがたい話.もっと広く一般にソフトウェア開発者にとっても,ありがたい話*2

とか書くとほぉらこういう輩が調子に乗る,となるわけだけど,悪意なき探求心みたいなものがこれはそうですよと常識的に明示できていれば認められるっていうことが認められたのはデカい話.

個人的な話に戻れば,逮捕より割と前に IRC だかで東大の中の人らしいよという風の噂を聞いて,東大ねぇ,やっぱすごいんだな,と思ったのが俺が人生で初めてちらっとでも東大を意識した瞬間であったりもしたので,俺にとっては影響力のあった人なんだよね.

逮捕の一件とかなくて,俺が順調に院にまで行けていたら直接教わる機会もあったのかもしれないと思うと人生はドラマチックだなぁと思わなくもない.

  1. 完全に筋違いなんだけど. []
  2. 洒落になってるんだけどわかるよね? いや, share の方ではなくて.っていう多重洒落. []

TWOR 解析 (1)

2 ゲッターさんが TWOR を頑張っている(混在 ZE おめでとうございます)のを見ていてオリジナル熱が出てきたはいいが打ったら絶望したので語るに落ちる*1

TWOR はとんがった種目なだけにスマートな攻略法はないものかと解析・考察される機会が多いような気がする. その流れ*2に乗って.

TWOR での運指がどうこうシフトがどうこう先読みがどうこうといった考察は一般タイピング論とでもいうものに吸収されるべきだと思うし,それは複雑系(笑)すぎて今適当にやってどうにかなるとも思えないので,エントリのタイトルの通り,解析に焦点を当ててちょっと頑張ってみよう企画(TWJ のワード抽出の続きでもあったり).

例によって一応概要を説明すると,TWOR の OR は 「オリジナル」 であってどうして「オリジナル」なのかは未だにわからないでいるんですがとにかくランダムっぽい英数記号をガリガリ打つ競技.

その TWOR の恐ろしい部分として,TWJR や TWEW では「ワード」という単位があるので部分に分解して読んだり練習することができるが,TWOR ではランダムな文字列がひたすらランダムに出てくるだけなのでとにかくその場で読んでその場で打ちこなすしかない! というものがある.初めて TWOR をプレイした時はそこになんだか途方もないものを感じる(はず).

だが実は,TWOR の出題文字列は完全にランダムというわけではなく,そこには頻出のパターンが存在している……ということが,TWOR プレイヤーの間では経験的に知られている.これは必ずしも断言されていないが,ある程度やり込んだタイパーであれば確信していると思われる.

にも関わらず詳細にまで突っ込んでその規則性・パターンについて調べた記録が見あたらない*3. 薄々感じてるのに詳細は明らかになっていないっていうのは気分が悪いので,目下このあたりを調査してみる. TWOR のワードセット的なものを調べる,と言ってしまうこともできる.

まあモラルの問題というか,それタイピングちゃう! チートや! に通じる部分というかが少なからずというか大いにある話ではあるので,公にやるには後ろめたいっつー気持ちもわからんではないし,過去の識者もそんなわけで自重してたのかなぁとか色々思わないでもないんですが,情報の透明化が叫ばれる 21 世紀,は関係ないにしろ昨今の風潮を見るに,大顰蹙ってわけでもなかろう……と傲慢にも思いまして,お友達を増やすべく,過程をそれなりに書くつもり. 解析推奨! とかこんなに簡単にチートができるぜ俺ってスーパーバッカー! とかそういう意図はまったくとはいわないけどほとんどなくて,より快適に気分よくストイックにうひうひタイピングを楽しむための燃料になればと思ってやってることをどうかご承知置き下さいませ(丁寧!)*4

さて,目的とするような解析を行うにはいくつかの方法があって:

  • 実際にプログラムを動かした結果を見て,そこから法則を推定する(観測)
  • データとしてのプログラムからソースコード(の再現)を得て,そこから法則を取得する(デコンパイル)
  • デバッガで実行中のプログラムの動作を追いかけ,そこから法則を理解する(デバッグ)
  • プログラムの作者に聞いてみる (ネタバレ)

と穏やかじゃないもの含め色々.

とはいえ二番目と三番目は手元に完全なロジックを含むプログラムデータがあり,かつ自由な環境でないと使えない*5し,突っ込んで勉強してないとできることじゃないので一般にはどうかと思う.四番目は今回のケースのように作者とユーザの距離が近い場合にはこれ以上なく強力だけど,禁じ手もいいところで興ざめなので,今は一番上の真っ当な観測によって進めよう*6

そんなわけで実際に TWOR を動かして,出題文字列を観測(記録)しようと相成るわけですが. その方法*7にもいくつか考えられて:

  • 出題文字列が格納されているメモリを参照する (直接参照)
  • GUI 周りの API を利用して,描画に使われている出題文字列を取得する (問い合わせ)
  • 画面に描画された結果を画像として読み込んで,出題文字列を抽出する (OCR)
  • タイパーらしく手でメモする (全手動)

オナニーで並べてるだけなので詳細は脚注行きだ*8が,ここでは三番目の OCR を採用.

表示されてる画像としての文字を見てその文字を特定するという,人間がやっていることに近いことをプログラムにやらせるわけで,これはまじめにやると論文になったり製品になったりという深遠なそれであることは素人目にも明らかなわけだけど,限定的なものなら素人にも書けてしまう.とりのさんが言ってたことにも影響を受けて,フォントファイルとかサイズとかスタイルとか文字集合とか全部手動指定するとようやく動き,拡大にも回転にもノイズにも全く強度がないというとても割り切ったスクリーンショット専用 OCR モジュール的なものを書いて*9,その子に TWOR の出題文字列を収集させる.TWOR といっても四種目あるけども,さしあたり(一番ハデな)すべキーをターゲットにしよう.

(……一晩で 40 円ばかりの電気代を消費……)

結果,一晩で 10 万のデータを得る*10. これについては公開して差し支えない物だと思うので,置いておく.

http://dvorak.jp/archive/twor_subekey_sample.zip (9.5 MiB)

解凍すると 20 MiB 弱の big なテキストファイルになるにょ! 一行が一度の試行で,すなわち各行 200 文字にょ! この長大なデータを統計的にあれやこれやすれば,あんなことやこんなことがわかったりわからなかったりするというわけだにょ! お暇な人は自分でやってみるといいにょ!

主に口調が盛り上がってきたところで次回に続く. 次回予告としてはいわゆるテキストマイニングによって TWOR すべキーの出題文字列の基本的な性質を明らかにし,TWOR の出題文字列には頻出のパターンが存在するということを統計的に検証します.(キリッ

と格好良くキめたところでアレなんですが,どなたか TWOR の数字モードについて,「時間帯によって数字の出方が違うな,朝だと昇順の並びが多めで,夕方だと……」 みたいな考察をしているページ知りませんかね. いつかどこかで見たんですが,失念. 多分 TWOR が極まってる人だったと思うので, Q さんとか,その辺なんじゃないかと思いつつ発見できていない. 心当たりあったらたれ込んでくれると喜びます.

  1. 誤用です.「語るに落ちる」は「えらそうなこと語るだけの奴になり果てる」という意味ではない,って当たり前すぎるんだけど,そういう誤用が増えているらしいぞ日本語が危ない! []
  2. というほど流れてないけど. []
  3. アンテナ低いんで知らないだけかもしれない.ご存じの人がいたら教えて plz []
  4. こんなくどくどした前置きがなぜ必要かは次の n 段落でわかります. []
  5. 具体的には,ネトゲーとか手元で動かないロジックがある場合や,自由にあれこれできないコンシューマゲームなどで無理. []
  6. デバッグもデコンパイル結果の解読も断念したからなんてことは……. []
  7. この辺が競技的な視点から見ると悪いことできちゃう証明になっていてアウアウ.変な方向に強調すると印象が良くないことは先例 @2004 からも理解してるつもりなのでそっちは敢えてスルーします. []
  8. 一番目は上でデコンパイルやデバッグを否定した理由と同様の理由で却下,二番目は使える状況が限られ,実際 TW では無理だったので残念,四番目は最終手段だが現実的に限界を感じるので却下. []
  9. 特にこの界隈では問題ありまくりなんで一般公開はできませんが. []
  10. 手動でこの数は死ねる. []