ポタージュを垂れ流す。

マイペースこうしん(主に旅行)

ポケットモンスターと擬似乱数

もうすぐ去年のセキュキャンから1年ですねー

ということでこのリレーブログ企画も一区切りするようで、おそらく僕の記事はこれで最後になるかと思います。

前回の僕の記事はこれ、前回の方の記事はこちらです。

amame.hateblo.jp

今回のテーマは擬似乱数です。ということで、ポケモンのゲームに使われている擬似乱数アルゴリズムをいくつか紹介してみようと思います。

アルゴリズムの紹介が本記事の目的なので、ポケモンの乱数調整に興味がある方向けの記事にはなっていません。また、セキュリティっぽい話ではないけど、暗号用途に適していない擬似乱数を使うと予想できちゃうということが分かりやすいかなと思ったという意図があります。

擬似乱数とは

今得られている数字の列から、次の数字が予測できないような数字の列のことを乱数列といい、乱数列の各要素のことを乱数といいます。

擬似乱数とは、乱数列のように見えるが、実際には確定的な計算によって求められている数列(=擬似乱数列)の各要素のことです。

擬似乱数は、例えば確率的現象のシミュレーションや、暗号を生成するために使われます。暗号用途に擬似乱数を用いる場合は、暗号学的に安全であるものを用いる必要があります(今回紹介するアルゴリズムはいずれも暗号用途に用いてはいけません)。

ポケモンにおける擬似乱数

上で述べたように、擬似乱数は確定的な計算に従っているので、入力初期値(seed値)がわかれば擬似乱数列自体を特定することが可能になります。

これを利用したのがポケモンの乱数調整です。例えば、伝説のポケモンで色違いで高個体値なものが出るような内部パラメータXがわかれば、それは疑似乱数生成器によって生成されているので、その値が出るような初期seed値を狙って出せさえすれば、初期seed値から乱数の生成(擬似乱数の計算式で次の値を求めること、ポケモンの乱数調整の文脈では「乱数を消費する」などといわれる)を繰り返して、狙ったパラメータXを得ることができます。

私はDS世代の乱数調整経験者なので、DSの場合について少し説明すると、初期seedはDS本体のMACアドレス、DS本体の時刻を基準としたソフトの起動時間などで決まり、1/30秒単位の操作が必要とされるものでした。

今回は線形合同法、TinyMT、xoroshiro128+を紹介してみようと思います。

線形合同法

線形合同法は、漸化式 $$ \begin{align} x_{n+1}=Ax_n+B\mod M \end{align} $$ に従って疑似乱数 $x_n$ を生成する方法です(ただし $ A,B,M $ は定数)。

ポケットモンスターシリーズの第3〜5世代(RSE、DPTHGSS、BW)で使われているアルゴリズム*1で、$ A,B,M $の値として $ A=1103515245,B=24691,M=2^{32} $、16進数で書けばA=0x41c64e6d, B=0x6073, M=0x100000000が使われています。

線形合同法の弱点として、$ M $が偶数の場合、この規則で生成される乱数列は偶数と奇数が交互にくるものが生成されてしまうというものがあります。ポケモンでは $ M $ が偶数になってしまっているので、0埋め右シフト>>>を使ってx_n >>> 16、つまり、16進数表記で $ x_n $ は8桁で表現(上位桁がなくても0があるとみなす)されますが、そのうちの上位4桁を擬似乱数として使っているようです。

TinyMT

ポケットモンスターXY(第6世代)において、また、ポケットモンスターサン・ムーン(第7世代)では、孵化(タマゴ)に関係するところにこのアルゴリズムが使われているようです。取扱説明書のライセンスの記述で発覚したとかなんとか。サン・ムーンはそれ以外のところにはMTの改良版であるSFMT(SIMD oriented Fast Mersenne Twister)というものが使われているようです。(MTはMersenne Twisterの略です)

ポケットモンスター サン 取扱説明書

使われている更新式はここから見ることができます。引用します。

内部状態にはstatus[4]として4つの数字の組、そしてmatmat2tmatというパラメータが使われているようです。

struct TINYMT32_T {
    uint32_t status[4];
    uint32_t mat1;
    uint32_t mat2;
    uint32_t tmat;
};
inline static void tinymt32_next_state(tinymt32_t * random) {
    uint32_t x;
    uint32_t y;

    y = random->status[3];
    x = (random->status[0] & TINYMT32_MASK)
        ^ random->status[1]
        ^ random->status[2];
    x ^= (x << TINYMT32_SH0);
    y ^= (y >> TINYMT32_SH0) ^ x;
    random->status[0] = random->status[1];
    random->status[1] = random->status[2];
    random->status[2] = x ^ (y << TINYMT32_SH1);
    random->status[3] = y;
    int32_t const a = -((int32_t)(y & 1)) & (int32_t)random->mat1;
    int32_t const b = -((int32_t)(y & 1)) & (int32_t)random->mat2;
    random->status[1] ^= (uint32_t)a;
    random->status[2] ^= (uint32_t)b;
}

github.com

ポケモンではリポジトリ内のsample.cで設定されているのと同じ値にmatmat2tmatは設定されているようです。具体的にはmat1 = 0x8f7011eemat2 = 0xfc78ff1ftmat = 0x3793fdffです。

ちなみに、この更新式は頑張ると $ s_{n+1}=s_n A $ みたいな連立方程式の形で表現できるらしいです。

xoroshiro128+

xoroshiroというのは、「xor」「rotate」「shift」「rotate」を略したもので、xorshiftという擬似乱数生成法の改良版にあたるようです。

ポケットモンスターソード・シールド(第8世代)のレイドバトルではこのアルゴリズムが利用されているらしいです。

xoroshiro128plus.cをみると、内部状態を $ (s_n^0, s_n^1) $ のペアで持ち、更新式は

$$ \begin{align} s_{n+1}^0 &= R\_l (s\_n^0,24) \oplus (s\_n^0 \oplus s\_n^1) \oplus ((s\_n^0 \oplus s\_n^1) \ll 16) \\ s_{n+1}^0 &= R\_l (s\_n^0 \oplus s\_n^1,37) \end{align} $$

ただし $ R_l (s,x) $ は64bit整数 $ s $ を $ x $ bitだけ左シフトして、あふれた桁を右側に付け足すようなものになっています。(イメージとしては、「12345」を2つ左シフトすると「34500」になり、あふれた「12」を右に付け足して、結果として「34512」を得る、みたいなことを2進数でやっている関数です。)

最後に、これで得られた $ (s_n^0, s_n^1) $ を用いて、 $ s_n^0 + s_n^1 $ で疑似乱数を得るようなアルゴリズムとなっています。


次の記事はこちらです

qwerty11.hatenablog.com

*1:第5世代ではメルセンヌツイスターも併用しているとかなんとか

善光寺の御開帳を見に行った

7年に1度ということで、長野の善光寺に御開帳を見に行きました。メインはこれでしたが、途中で気になるスポット(松本、糸魚川など)も回収しつつ、北陸の第3セクター区間もそんなに乗る機会もないかな〜ということでルートを策定。本当に旅行するかどうかは前日まで迷っていましたが、まあやっちゃえ、と思ってやることにしました。

6/28(火)

京都から長野方面行くのけっこう時間がかかって何使おうか迷ったのですが(高速バスという選択肢もありえた)、途中でどこ降りるか迷ってたというのもあって鉄路を選択。遠いので鈍行だと時間がかかって疲れるということで特急に課金。新幹線で京都から名古屋へ向かい、そこで乗り換え特急で松本へ向かう。

松本駅に到着。クッソ暑い。

ちょうどお昼だったので信州そばでも食べるかということで、駅前の立ち食いそば屋さんで昼食をすませる。松本は山賊焼きが有名らしいので、山賊焼きセットを頼んでみた。

そば

松本といえばここだろ、ということで、松本城にきた。黒くてかっこいい。

松本城

少し前に松本城のお堀のコイがめっちゃ群がってる画像でバズってた記憶があったので、コイいるかな〜と探したのだが、1匹くらいしか見つけられなかった。みんな暑さでやられちゃってるんですかね。

他の人には松本城以外の松本市内の観光地思いつきますかみたいな質問してたみたいで面白かった。そういう質問を僕にもしてほしかった。

駅とお城の間に四柱神社という願い事結び系の神社があったので院試合格などをお願いしておく。

四柱神社

縄手通りなどを歩き、松本市美術館へ。松本は草間彌生の出身地みたい。

松本市美術館

大いなる巨大な南瓜

途中で深志神社とかいうのがあったので立ち寄りつつ、松本駅に戻ってきた。駅前の温度計は38度を指していた。暑い。

駅中のnewdaysで水を購入。おいしい。

恒例のスタバスタンプ埋め。長野に行く途中に通過する姨捨あたりで日没時間を迎えたかったので少し時間調整 兼 事務作業。

8つ目

いい感じの時間になってきたので、夜ご飯を食べる。量めっちゃ多くてハーフも選べたのだが、持ち帰りができるみたいなこと書いてあったのでそうすることにした。キャベツもおかわりし放題。本当はおかわりしたかったけど、時間の都合上断念。

山賊焼き

普通列車に乗って長野方面へ。姨捨駅で下車。次の電車まで50分くらいある。

日没前の姨捨

ちょっと歩くと公園があるので、そこでぼーっとしていた。

日没後の姨捨

日本三大車窓と言われているだけあって綺麗ですね。ここ以外だと狩勝峠は制覇しているのであと残るのは九州ですかね。

普通列車に乗って長野駅へ。駅も御開帳モードになっていた。

長野駅

駅近くのドミトリーに宿泊。1泊2500円で安く、そこそこ綺麗だったので良かったように思う。リンクを載せておこう。

nagano.mashcafe-bed.com

ネットの速度が異常に速かったのでパソコンで作業する人にはかなりおすすめかもしれない。

6/29(水)

朝6時台に起床。善光寺へ向かう。この日が御開帳最終日になっていた。

7時半くらいに到着したが、既に御朱印のところは1時間以上待ちになっていた。他はそこまで混んでいないとはいえ、この時間にしてはかなり人がいるように感じる。

回向柱

7年に1度しか見れない前立本尊を見て、御印文頂戴とか、お戒壇巡りとか、やれることは全部やった。朝早かっただけあってか、待ち時間はほぼなかった。(ちなみに本堂内は撮影禁止です)

captionはよく読もうね

善光寺を後にして、権堂駅方面へ。

商店街を歩いていたらめっちゃ味のある映画館を見つけていいですねになっていた。

映画館

かつて成田エクスプレスとして使われていた車両に乗って小布施へ向かう。小布施駅到着前には「栗と北斎のまち、小布施です」というアナウンスが流れていた。

北斎館へ。葛飾北斎の絵をいっぱい見ることができる。入館料が1000円でちょっと高いが、葛飾北斎は多くの人は知ってるので大抵の人は楽しめそうに思う。

実際に刷ってあるのはじめてみた

竹風堂の小布施本店へ。旬の時期ではないが、栗が食べたかったので。山家定食を注文。当然美味しい。栗おこわもよかったが、ニジマスの甘露煮も味噌汁もよい。りんごジュースがサービスで出てきた。

山家定食

途中のスーパーで飲み物を買いつつ、岩松院へ。葛飾北斎が描いた絵の中で最大規模の作品である八方睨み鳳凰図が描かれている(撮影禁止)。また、小林一茶が『やせ蛙まけるな一茶これにあり』の句を詠んだ蛙合戦の池があったり、福島正則の墓があったりする。

お寺のガイドさんが20分に1回説明してくれる。ガイドの時間外でもいろいろ教えてくれたりして面白かった。

蛙合戦の池

小布施駅付近に戻る。モンブラン朱雀をいただく。ウマイ

モンブラン朱雀

思ったより早く回れてしまったので、少し足を伸ばして湯田中へ。バスに乗り換えて渋温泉へ。いくつかのサイトには16時までと書いてあって、この場合は時間的に無理だったが、公式をみると17時までとのことだったので、公式を信じた。

渋温泉には共同浴場が9つあるが、その中で渋大湯だけ日帰り入浴可能。観光案内所で入浴券を購入し、近くの旅館の人に大湯の鍵を開けてもらう。

入浴券 ポストカードになっている

お湯が熱いという話を聞いていたが、確かに熱い。脱衣所の床もかなり熱い。お兄さんに話しかけられる。

渋大湯

浴場の建物から出ると、外の方が涼しかった。明らかに熱中症になりかけていたので金具屋旅館前にあった自販機でポカリを購入。一瞬で1本がなくなった。日陰で休憩。

ところで、金具屋旅館というのは千と千尋の神隠しの湯宿のモチーフになったとも噂されている旅館で文化財指定もされているらしい。

金具屋旅館

ちょっと温泉街を散歩し、そろそろ帰るか〜と戻るバスを調べたら1時間半待ちみたいな感じだったので、仕方なく湯田中駅まで徒歩で向かう。

のどかですね

湯田中駅に戻ったが、電車の時間を間違えており1時間待ちみたいな感じになってしまう。駅前温泉があるのでそこで時間を潰す。中でさっき渋大湯で会ったお兄さんに再会して少し話す。

温泉むすめのパネルを見つける。

いい時間になったので駅へ戻り、電車に乗って長野駅へ。信州中野駅で乗り換える。

長野駅到着。あっさりしたものが食べたかったので再びざるそばをいただく。

信州そば

普通列車でひたすら北上する。

上越妙高駅で降りる。今日はここで泊まることにする。

マンガ読んでたら寝れなくなった

6/30(木)

おはようございます。

上越妙高駅から糸魚川駅まで新幹線を利用。

フォッサマグナミュージアムへ。

自分は正直あまり岩石とかには興味がないが、プレートとか大陸とかの動きには興味があるタイプの人間。地理を勉強してるだけでは出てこないような地学的な話を見ることができて面白かった。糸魚川近辺で取れるヒスイが日本の歴史に重要なものになっているみたいですね。

地震計とか置いてあって計測器オタクはニチャつき顔になっていた。

宝石の国の伏線回収か?

ちょっと時間があったので長者ヶ原考古館にも立ち寄ってみたがあまり興味をそそられる内容ではなかった。歴史に対する興味が浅い。

遺跡にも行ってみたが虫が多くて単純に嫌な気持ちになって戻ってきた。

お昼時になったのでご飯屋さんを探す。B級グルメとしてブラック焼きそばというものがあるらしいのでそれを食べる。

糸魚川ブラック焼きそば

ランチサービスでコーヒーがいただけた。中華料理店なので、次来る時は是非麻婆豆腐を食べたい。

お店の向かいあたりに相馬御風の宅みたいなのがあったが時間の関係で断念。早稲田大学の校歌作った人らしい。

海が見れる展望台があったので登ってみた。西の方を見ているが、東の方にはヒスイ海岸なるものがあるらしい。

展望台から南の方を見ると、フォッサマグナの凹みを感じることができた。

フォッサマグナ

マンホールカードを回収。キターレ内には糸魚川大火についての展示がしてあるが、机やイスがある多目的スペースみたいになっており、JKが勉強していた。キターレ付近は2016年に大火があって焼けてしまったエリアになるらしい。現代になっても大火といった概念が発生しうるというのは驚きである。それもあって雁木がやけに新しかった。

糸魚川駅に戻り、駅の中にあるジオパルへ。糸魚川ジオパークの説明とか、トワイライトエクスプレスの再現車両とか、デカい鉄道模型があったりした。

糸魚川を後にし、ひたすら京都方面へ向かうことにする。途中何処かに立ち寄る時間はあったが、乗り換えを何回もするのが面倒だし、途中で立つのは嫌だな〜と思ったのでそのまま帰ることに。きっとまた来るでしょう。

ここでわざわざ上越妙高から糸魚川まで新幹線を使ったことの伏線回収。北陸新幹線を、新幹線eチケットを利用して東京〜上越妙高から乗車し、糸魚川〜金沢間に到着するという条件を満たせば北陸周遊乗車券というものを購入することが可能となる。これだけで北陸の第3セクター区間を抜けることができ、近江塩津や長浜まで行けてしまうので超お得。

北陸周遊乗車券

ひたすら西へ。

富山駅からめっちゃ人が乗ってきた。途中で通る高岡はいつか観光したいと思っている。

金沢に到着。

北陸に行ったらいつも買っているますのすしの駅弁を購入。

進行方向左手に北陸新幹線の高架を見つつ、敦賀に到着。湖西線経由の京都行きに乗り換える。

到着

おつかれさまでした。ギリギリ学食に間に合った。

行程表

6/28(火)

6/29(水)

6/30(木)

京都大学大学院情報学研究科先端数理科学専攻の推薦入試に合格しました

タイトルの通りですが、京都大学大学院情報学研究科先端数理科学専攻の修士課程推薦選抜を受験し、合格しました。

受験理由

友達に成績良いんやから受けたらいいんちゃう?と言われ、特にデメリットはない(後述)ので受けてみようかな、と思って受験することにしました。推薦入試を受けるなんて機会そうそうないですからね。

ちなみに、京大院の情報学研究科で推薦入試制度が設けられているのは、知能情報学専攻と先端数理科学専攻だけです。知能情報の方は博士課程進学が前提らしいと聞いたことがありますが、先端数理はその限りではないです。

デメリットがないというのは、推薦を受けて落ちてしまったとしても一般入試を追加料金なしで受けられるというもので、単純に受験機会が増えて嬉しい気持ちになります。それに、合格発表も7/1と早いので、受かればその後は院試に縛られることなく好きにできます。遊んでもいいし、勉強してもいいですね。

ちなみに、成績(GPA)は全体では3後半、専門科目だけで見れば4くらいで、推薦で合格している先輩を見る感じだとそこまで良くはないのかなあとは思います。

院試まで

京大工学部情報学科の数理工学コースでは、4月中下旬ごろに研究室配属がされます。僕は(希望通り)先端数理科学専攻の研究室に配属されました。先生方が推薦受けたいならGW明けくらいには教えてねと仰っていたので、GW明けくらいに先生にお伝えしました。

受ける前にどういう研究がしたいかちゃんと考えて指導教員を決めないといけないので、先生方に時間をとってもらって、こういう研究がありますみたいなのを1対1で1時間程度お話を聞けたのはかなりためになりました。

推薦入試では、願書を出すにあたって指導教員からの推薦書が必要なので、推薦書の参考になりそうなこと(志望動機とか、これまで勉強したこととか、勉強に限らない活動とか)をお伝えして書いていただきました。

推薦書には成績表のA以上の数を書く欄があって、これを数えているときに、うわっ自分のA以上の割合少なすぎ...?になっていました。

ちなみに、成績表を先生に見せた時もA以上の科目も多いけど、Cとかも多いねえ、と不穏なことを言われていました。

志望理由書も先生に添削をお願いしました。よく書けていたらしいです。

5月末に願書を出しました。

理研の方でお世話になっている先生の漢字を間違えていました。ごめんなさい。出願後に気づいたのでアになりました。

6月中頃に受験票がきました。本番を待ちます。

口頭試問

推薦選抜でみられる内容は提出した書類と口頭試問だけです。

指定日時に控室に出頭してその時を待ちます。

口頭試問の内容とか雰囲気は人によって違うらしいのですが、僕の場合を書きます(書きすぎるのは本当はあまり良くないのかもしれないですが)。

控え室に先生が呼びに来て、会場の教室に案内されます。会場に入ると、黒板の前の教壇にパイプ椅子が2つ用意されていて、椅子に荷物を置いて、座ってくださいと言われました。いつもの講義と立場が完全に逆で、教壇には僕1人、席には教授たちが30人くらい?座っていらして、全員が僕の方を見ています。人生史上最高レベルの緊張で脳が止まります。

はじめに形式的な質問(受験番号は?とか)がいくつかありました。

次に基礎科目についての口頭試問を始めますということで、

「単振り子のふるまいについて説明してください」

と言われ、黒板に書いて説明することになりました。

これくらい推薦を受けるような人間なら誰でも答えられると思いますが、緊張で脳が止まっているので運動方程式を立て間違えてなんかおかしいなとかなります。

周期とかこうなりますってなんとか説明し終えたら、

「張力はどうなりますか」

って聞かれてそっちのこと考えるの忘れてたなとなり、答えます。

「張力をTとすると...」

「周期でTを使っているので、張力の文字を変えた方がいいですよ」

「あ、はい...どうしようかな...じゃあSにします」

脳が止まっているので、質点に乗った観測者から見たところの遠心力を考慮し忘れて、普通に間違えます。

「本当にそれであっていますか?」

脳が完全に停止しました。

「どういう仮定を置いていますか?」

あっち側から落胆した雰囲気を感じつつ永遠の時間が過ぎます。黙ったら終わると思って、実際には何も考えていないのですが、あー、とか、えー、とか言っていました。

「質問を変えます。極座標での運動方程式は書けますか?」

助け舟が出ました。

なんとか一通り説明を終えることができました。これで終わりかと思ったのですが、別の先生から

「君は変位が十分小さいからって言って近似を使ったけど、何に比べて十分小さいんですか?」

「何に比べて十分小さいか、考えたことはありますか?」

脳が停止しているのにこんなことを聞かないで欲しい。咄嗟に説得力のある例えを言うことはできませんでした。

「考えたことがないわけではないですが...」

固まっていたら次の質問がきました。

「では、近似なしの場合はどうなるか知っていますか」

「楕円積分が出てきます」

「どういう過程でそれが現れるかは覚えていますか?運動方程式積分する前ですか?後ですか?」

「...覚えていません」

これ答えられないの最悪だな(ちょっと考えればエネルギー積分してあーだこーだすれば良いことがわかる)と思っていると

「これで基礎科目についての質問を終わります、椅子に座ってください」

戻って椅子に座ります。

以降は志望理由書に書かれていることを聞かれました。いま宇宙放射線関連の論文を書いているので、それに関連することが多かったように思います。修士終了後の進路として就職のつもりだが未定みたいなことを書いていたので、もし博士課程に進むとしたらどういう場合にそうするか?みたいなことを聞かれ、

「研究が楽しかったら博士課程に進むと思います」

とか言ってしまっていました。もうちょっとそれっぽい回答できただろ。

「以上で口頭試問を終了します。退室してください」

「ありがとうございました」

なんとか口頭試問が終わりました。僕から見て左奥にいた教授が僕の回答に対していつも頷いてくれていたのが心の支えになっていました。

上の通り、受け答えが全体的に最悪で本当に落ちたなと思っていました。

冷静に考えれば答えられることを答えられなかったのは精神的にもかなり辛かったです。なので受験後は旅に出ていました

口頭試問はこの通りメチャクチャだったのですが、合格していました。きっと志望理由書に書いたこととか成績とかを評価していただけたのだと思います。

ちなみに、今年は推薦入試受験者(3人)は全員合格していました。弊研は僕含めて2人合格でした。一般の枠めっちゃ少なくなっちゃってるけど大丈夫ですか?

(追記)一般入試でこの研究室の内部生みんな落ちたみたいで僕は悲しいです...

さいごに

院試に受かったのはよいのですが、来年から仕送りがなくなるので、学費を稼ぐために仕事を探さないといけません。大変ですね(他人事)

情報処理安全確保支援士試験に合格しました

タイトルの通りですが、情報処理安全確保支援士試験に合格しました。

情報処理安全確保支援士試験とは

長ったらしい名前の試験ですが、セキュリティスペシャリストとか、セキスペとか言われている試験です。国内で受けれるセキュリティ系の試験の中だと最難関らしい。

詳しい話はここを読んでもらう方がいいかも

www.sc-siken.com

登録セキスペとかいうのになればそれを士業にして独立してセキュリティコンサルタントとかできるらしい。登録料高いしならんけど。セキュリティキャンプフォーラム行った時にIPAの人に会う機会があったけど登録料高いから例えば学生さん向けに学割みたいな制度作ればいいのにって言ってた。

受験動機

セキュリティキャンプに参加したとはいえ、セキュリティのことなんもわからんな〜となったから。

実際これきっかけでセキュリティに関することは色々と知ることができた。個人的にはAPの時より学習効果を感じた。

したこと

3月上旬 中旬

勉強らしい勉強はあんまりしてない。とりあえず本を読んでた。あんまり頭には入ってない気がする。

マスタリングTCP/IP 情報セキュリティ編 | Ohmsha←最近第2版でたね

www.sbcr.jp

3月下旬

とりあえず本格的な対策本を買った。

www.seshop.com

とりあえず全部読む気でいたけど1/3くらい読んだところで4月が見えてきて、どう考えても時間足りんなとなったので辞書的な使い方をすることになった。

3/28〜4/2

いわゆる緑本を買った。APの時もかなり良い参考書だったので。3/30くらいからやり始めた。

2022 情報処理安全確保支援士「専門知識+午後問題」の重点対策 | IT資格試験の取得、IT人材育成は株式会社アイテック(iTEC)

午前Ⅱ対策もこれくらいに始めた気がする。午前Ⅱは過去問と同じ問題が半分出るので、過去問さえやっておけばOKと判断して過去問道場を隙間時間にやってた。

4/3〜4/9

緑本をとにかく進める。問題を解いてると本読んでるだけだとふ〜んってなってたことが、だんだんわかってくる。

なんとか緑本を1周する。

4/10〜4/16

緑本の2週目に入る。緑本に入ってない過去問をR03秋から遡って解いていった。

4/11にこの本を買って一気読みした。めっちゃ分かりやすくて初めからこれ買えば良かったになった。個人的には暗号技術入門より好き。

gihyo.jp

4/17

本番当日。会場はまさかの京大。部屋も情報数学か振動波動論かで使ったことある部屋だった。

手応え

  • 午前Ⅰ

AP持ってるので免除

  • 午前Ⅱ

15/25わかってたので通過

  • 午後Ⅰ

  • 午後Ⅱ

合格

次はネットワークかデータベース取るのがいいですかね

第2次スマートホーム化計画

potaxyz.hatenablog.jp

これから約3年

当時もswitchbotは存在したけど、hubとしては雲の形のやつしか売ってなくてデザインが嫌いだなあ、となってnature remoを選んだ記憶がある。

が、月日が流れ、主張してこないデザインのswitchbot hub miniが発売され、switchbot製品が充実してきた昨今、ただの汎用リモコンでしかないremoではカーテン自動操作したいとか玄関の鍵の開け閉めも自動化したいとなると、別の会社の製品を買わないといけなくなるのが嫌だなあという感じに。

そこで、いっそswitchbotエコシステムに乗り換えてしまおうということで、一気に製品を購入。

購入

一式購入
一式購入

  • switchbot hub mini (x2)
  • switchibot hub mini専用 echo flexコネクタ
  • switchbot ボット
  • switchbot 湿温度計プラス
  • switchbot カーテン
  • switchbot ロック

計: 27,230yen

amazonのタイムセールの時に買ったので普通に買うよりは安くなっているはず。

やりたかったこと

  • リビングのシーリングライトの操作自動化(remoからの乗り換え)
  • エアコンの操作自動化(remoからの乗り換え)
  • カーテンの開閉の自動化
  • 玄関の開閉自動化
  • 玄関のでんき自動化
  • 部屋の温度と湿度の確認

自動化って言ってるけどタイマー設定したら自動で動くとか、スマホで操作できるとか、alexa経由で声で操作するとか、ちょっと広い意味でのそういうことを指しています。

設置

リビングのhub

nature remoが刺さってたusbのとこをそのままswichbot hub miniに変更。まだテープとか貼ってなくて放置されているのでそのうち良い感じにする。

シーリングライトとエアコン

シーリングライトはリモコンの赤外線を学習させた。エアコンはswitchbot側が用意してるデータベースに製品があったみたいで赤外線学習させずに設定が完了した。風向きは変えれないみたいでその点はnature remoに劣るが、そこまで気にならない気もする。スマホからのリモコンメニューの見やすさはnature remoの方が優れている気がするが、どうせalexa経由で声でしか操作しないし、細かい操作はそんなにしないので気にならないと思う。

switchbotとnature remoとのスマホのリモコン比較

ライトのリモコン(switchbot)
ライトのリモコン(nature remo)
エアコンのリモコン(switchbot)
エアコンのリモコン(nature remo)

温湿度計プラス

nature remo miniでは温度しかわからなかったけど、温湿度計を買ったので温度も湿度も確認できるようになったのは嬉しい(alexa経由で声で温度の確認もできる。湿度は無理?)。1分ごとにデータを取ってるみたいで、csvでエクスポートできたりするのも嬉しい。温度は0.1度刻み、湿度は1%刻み。

ちなみにプラスと普通のやつの違いは値段と、サイズと、快適度マークが出るか、あと記録が残る期間がちょっと長いとかくらいらしい。

nature remoであれば本体があるだけで温度(miniを使っていたので湿度は測れなかった)が確認できたが、やっぱり目で確認できるものがあるといいなという気持ちになった。

温湿度計プラス
温湿度の履歴が見れる

カーテン

カーテンの開閉が自動でできるようになったので、1日中カーテンは閉めっぱなしみたいな状況は防げる気がする。とりあえず朝タイマーで開くようにして昼夜逆転が解消することを祈る。夕方になったらタイマーに自動で閉めるようにして閉め忘れてたみたいなのも防げそう。スマホからだと開き具合もパーセントで指定できるのが良い。alexaで操作する場合は全開か全閉しかできない。

GIF画質悪いな

カーテン

カーテン操作

玄関のhub

リビングのhubからだと位置的に玄関内のやつには届かない気がしたので購入。もしかしたら不要だったかもしれないが...

玄関に設置されていたecho flexに専用コネクタでくっつけた。

玄関のドア

設置する向きを迷って2、3回つけたりはずしたりしてたので粘着力弱まっててそのうち取れてしまう気がするが今のところ大丈夫そう(3Mテープで接着するようになっている)。ドライヤーで熱すれば普通に跡なくはがせる。正直いつも鍵は持ち歩くしなくてもいいと思ったが、スマホで施錠状況が確認できるし、鍵の閉め忘れがあれば通知してくれるし、家入った時にalexa鍵閉めてみたいなこと言えば鍵閉まるし、便利。旅行行く時に閉め忘れの心配をしなくてよくなったのがかなり良いかも。

GIF画質悪いな2

ドア

玄関のでんき

玄関のでんきは賃貸備え付けのスイッチでしか操作できないので、switchbotボットで直接スイッチを押してもらうことにした。たまに消し忘れるので声で消せるので便利になったと思う。

alexaに認識させるときにタイプが照明かスイッチかで選べるが、ここではスイッチを選んでおく方がよい。照明を選んでしまうとシーリングライトの方と競合して、シーリングライトに「でんき」と名前をつけていた場合に素直に言うこときいてくれなくなってしまう。

玄関のでんきはどう名前つければいいんだろう?と思ってとりあえず玄関ライトにしてある。(でんきというフレーズのせいで競合が発生するため。)

直接

「安全ではないデシリアライゼーション」についてpythonのpickleから少しだけ理解する

例によってリレーブログの時間です!前の僕の記事はこれ、前回の方のブログはこちらになります。

amame.hateblo.jp

今回のテーマは「安全ではないデシリアライゼーション」です。

リアライゼーション / デシリアライゼーションとは

リアライゼーションとは、プログラムの実行状態や複雑なデータ構造などを、バイト列やjsonといった直列化された形式で表現することです。今回紹介するpickle形式もその形式の1つです。pythonではdump()とかdumps()関数を呼び出して直列化することが多いと思います。

逆に、デシリアライゼーションとは、シリアライゼーションされたデータを元の状態や形式に復元することです。

pickle

pythonでは、pickleモジュールを利用することでオブジェクトをバイナリ形式でpickleファイルとして保存することができます。利用用途としては、例えば、機械学習などでモデルを学習している途中の状態をpickleファイルで保存したり、学習済モデルのpickleファイルを読み込んで利用する、なんてことに使われています。

pickleめっちゃ便利やん!とはなるのですが、pickleファイルをデシリアライズする際にセキュリティ面の考慮がなされておらず、シェルコードの実行ができてしまいます。悪意のあるpickleファイルであればリモートコード実行とか色々できてしまいます。

pythonのdocumentのpickleの項目にも、

警告 pickle モジュールはエラーや不正に生成されたデータに対して安全ではありません。信頼できない、あるいは認証されていないソースから受け取ったデータを非pickle化してはいけません。

との記述があります。

また、昔はDjangoのセッション管理にpickleが使われていたようで、SECRET_KEYが第三者に漏れると悪意のあるpickleが作れて、悪意のあるcookieが作れてしまうとかそういう脆弱性があったようです。

やってみる

試しに、中身が以下のようになっているExample_bad.pickleを用意しました。

cos
system
(Vecho I\'m gonna pickle you! > message.txt
tR.

これを読み込んでみます。

import pickle

with (open("Example_bad.pickle", "rb")) as f:
    p = pickle.load(f)

これを実行すると、アヤシイExample_bad.pickleを読み込んだだけで、カレントディレクトリに「I'm gonna pickle you!」の記述があるmessage.txtが作成(もしくは、存在していれば置換が)されてしまいます。「お前を漬物にしてやる!」、なんて怖いメッセージでしょうか。

この例はかなり簡単なものでしたが、システムに損害を与えてしまうようなコードが実行できてしまうことを想像するのは難しくないと思います。

まとめ

安全ではないデシリアライゼーションに気をつけよう!

次のブログはこちらです

qwerty11.hatenablog.com

KRACKs

例によってリレーブログの時間です!前の僕の記事はこれ、前回の方のブログはこちらになります。

potaxyz.hatenablog.jp

amame.hateblo.jp

今回のテーマは「KRACKs」です。

KRACKsとは

KRACKsとは、Key Reinstallation AttaCKs(鍵再インストール攻撃)の略称です。2017年10月に公表されました。

内容としては、スマホなどの無線LANクライアントがWPA2でアクセスポイントと接続する際の「4ウェイハンドシェイク」という処理の仕様における脆弱性です。

「4ウェイハンドシェイク」では、クライアントがアクセスポイントとの間で暗号化通信を行うために認証や暗号鍵に関するメッセージをやりとりします。名前の通り、4つのメッセージをやりとりするものです(話の都合上1つ目、2つ目のメッセージについては省略します。)3つ目のメッセージがアクセスポイントからクライアント側に送られるもので、このメッセージによってクライアントに鍵がインストールされ、4つ目のメッセージが3つ目のメッセージの確認応答となっています。

4つ目のメッセージを送った後、クライアントは暗号化通信を開始します。

ここで、最後の4つ目のメッセージを中間者攻撃によって意図的に止めると、アクセスポイントは3つ目のメッセージがクライアントに届かなかったと判断して再送します。

クライアントは、3つ目のメッセージを受け取るたびに鍵を再インストールして暗号化通信のための処理をやり直すので、暗号文を送るのに使われるナンス(Number used ONCE: nonce、本来は一度しか使われない数)に同じものが使われてしまいます。

この3つ目のメッセージを意図的に再送させ続けることで、クライアントからアクセスポイント側へは本来は時間とともに変わるはずであったのに同じナンス、同じ秘密鍵で暗号文が送られることになるので、暗号化されたフレームを解析すれば暗号化パターンがわかり、通信データを盗聴できてしまいます。

対策

この脆弱性が発覚してから、セキュリティパッチが配布されるなどして対策が進んでいます。

また、webサイトを見るときはHTTPS(このSはセキュリティのSで、暗号化通信がされる)で接続していれば、WPA2での暗号化が破られても、HTTPSの暗号化はされているので、安全性が高まります。(WPA2とHTTPSで二重の暗号化)

また、WPA2の脆弱性に対処したWPA3という規格も2018年に発表されました。

WPA3は、4ウェイハンドシェイクの前にSAEとよばれる楕円曲線を用いたハンドシェイクの仕組みが導入されたもので、仮にパスワードが漏洩しても、そのときの鍵共有の結果はわからないものになっており、これによってKRACKsを無効化できるようになりました。

とはいえ、WPA3にも脆弱性が発見され、それに対策して...というのは続いています。

参考文献

次回はこちらです。

qwerty11.hatenablog.com