読者です 読者をやめる 読者になる 読者になる

HHKB Lite 2 を買いました

貸与されるPCを使用することになったのですが、Aの隣にControlが無いと死んでしまう病に罹っているので購入して1週間ほど使用してみました。

購入

Amazonアウトレットからの商品が通常の商品より1000円ほど安かったのでこちらから購入しました。 倉庫内で梱包に傷を負ったものや返品されたもののうち、審査により通常使用には問題ないものを扱っているようです。

Amazon.co.jp出品者プロフィール:Amazonアウトレット

購入した商品のコンディションは以下のようになっていました。

コンディション: 中古品 - 良い - 商品は開封済で底面に傷、擦れがあります . 外装に多少の損傷があります .

底面に傷があるとのことで購入を若干躊躇したのですが、実際の商品ではどこにあるのか全然わからない程度でした。

使用感

なお今までは Thinkpad X240 を主に使用していました。

最初触った瞬間の感想としては、キートップが狭い気がしたり、ラップトップのキーボードに慣れているせいかちょっと疲れる気がしたりしましたが、すぐ気にならなくなりました。 慣れですね。 他には右 Ctrl が無くVirtualBoxのホストキーの割り当て問題がありましたが、右 Alt に再割り当てしたので今は困っていません。 また矢印キーが一段低くなっていてなんとなく押しやすくて地味に便利です。

一方まだ慣れない点としては、 Shift が少し短く隣の Fn誤爆しそうになる点、 `Backspace/ などの Thinkpad のキーボードレイアウトとの差異により切り替えたときに戸惑う点あたりでしょうか。

さいごに

Professional と比べられがちな Lite 2 ですが、今の自分には十分に高級キーボードでした。

PFU Happy Hacking Keyboard Lite2 英語配列 USBキーボード ブラック PD-KB200B/U

PFU Happy Hacking Keyboard Lite2 英語配列 USBキーボード ブラック PD-KB200B/U

テストメソッドをもっと雑に使ってもいいんじゃないか

これは kstm アドベントカレンダーの22日目の記事です。新鮮なネタは無いので過去のツイートを元にポエムを書きます。

qiita.com

なお、設計能力の無い学生が何らかのフレームワークを使用してWebアプリケーションを構築する前提で話します。

TL;DR

なぜこんなことを考えたのか

xUnit がどこでも同じように使えそうだった

今使っているフレームワークがフィクスチャをロードするコマンドなどを提供していなかったため別の手段が必要だったがちょうど使えたのがテストだった、というのがきっかけで、テストを単なるタスクランナーとみなして良いのではと思い始めました。もちろん、パッケージマネージャやアプリケーションフレームワークがタスクを実行するための機構を提供していたりするのですが、そのインターフェースはそれぞれ異なり、覚えるのが面倒です。一方 xUnit 系フレームワークは多くの言語に存在し、そのインターフェースは似通っています。そして多くのアプリケーションフレームワークがサポートしており、そしてフレームワークによってはテストメソッドからDIコンテナが呼べるようになるなどの拡張が提供されていたりします。よって定常的に実行するタスクならばコマンドに移植する必要があるかと思いますが、自分しか使わなかったり、暫定的にしか使わなかったりするタスクについてはテストメソッドで十分なのではないかと思います。

開発の足場としての Controller の代替

ところでアプリケーションに新機能を追加する、という場合、みなさんはどのように開発しているのでしょうか。私は直接 Controller に Action 生やして、ページ上に print デバッグしながら機能を作っていました。唯一知っていたのがその方法だったからです。

PHPフレームワークなんかだとWebページをリロードするだけで変更が反映されたり、ダンプを見やすく整形して表示してくれる関数があったりするのであまり負担ではないのですが、JavaなんかだとWebアプリケーションをリスタートするのが案外時間がかかったりするため、テストメソッドでデバッグしたほうがトライアンドエラーがしやすかったりします。

また、Controllerに直接書く場合、Controllerに密結合なコードを書きがちでかつ、動いてしまうことに甘んじてリファクタリングせずにそのままプロダクションに投入しがちになる気がします。本来は新機能におけるビジネスロジックはその責務を負う別のクラスに切り出されるべきで、テストに書く場合、そのままではアプリケーションからは利用できないので移植することが必要となるため、これがリファクタリングの契機になったらいいなと考えています。

ユニットテストなんだかんだで書けない問題

TDDではテストファーストが原則となっていますが、これには何をテストするか明確になるまで設計する必要があります。しかし開発経験が浅い場合、要件が曖昧、フレームワークの知識が浅い、設計のノウハウが無いなどの要因により、事前の設計ができず、コードを書いてみて、試行錯誤しながら徐々にコードが固まってくるというプロセスになる気がします。したがってTDDの話を見知ってテストファーストをしようとしても何をテストしたらよいかわからず挫折するように思います。

一方でテストラストの場合、テスト対象が試行錯誤の末ある程度まとまったときにテストを書くため、開発過程の手助けにはなっていません。また、設計能力が無いので設計が良くなかったり仕様が曖昧だったりして、開発中に仕様が頻繁に変わる可能性があります。この場合テストコードも変更しなければなりません。さらに、ユニットテストではアプリケーションがエンドツーエンドで正しく動くことは保証できないため、銀の弾丸にはなりません。こういった状況により、テストによる恩恵よりも負担が大きくなり、テストを書くメリットが享受できずテストが書けないように思います。

print デバッグとテストは似ている?

Webページ上で print デバッグしながら開発する場合、明確でないにせよ、なにかぼんやりと期待した動作というものが心の中にあって、それがトライアンドエラーを繰り返すことで明確化していき、最後 print デバッグした出力が期待したとおりの出力になっていたときに機能が実装できた状態になる、というプロセスになる気がします。これは大枠としてはTDDのレッドグリーンリファクタリングのサイクルと変わらないのではと思いました。うまくいけば、 print 文を assert 文に替えるだけでもしかしたらテストになるかもしれない。

私は何もわからなくてもとりあえず実践する機会を増やす、というのは向上のきっかけになると考えています。とりあえず雑にトライアンドエラーする場所としてテストメソッドで作業することでテストを書くためのきっかけになるのでは、という期待があります。

おわりに

書いてみたけど全然まとまりませんでした。ありがちな問題という体で書いていますが、自分が陥ってい(た|る)問題であり、どう改善していくのが良いかというのは自分でもよくわかりません。テストを書いて幸せになりたい(なれるとは言っていない)。

WhiteHat CTF 2016 Writeup

WhiteHat CTF 2016 に Team:Harekaze で参加して1問だけ解きました。

Banh bot loc (Web 100)

@lv7777 さんにより /index.php.bak にアクセスすることでソースが降ってくることが分かっていました。

<?php
    function checklogin($username, $password, $key, $secret)
    {
        if($username.$key == md5($password))
        echo $secret;
    else echo "noob";
    }
$key = "1337";
$secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
echo "<html>
    <title>hello</title>
    <body>
    <a href='index.php?username=guest&password=guest'>login</a><br>
    </body>";
if (isset($_GET['username'])&&isset($_GET['password']))
    {
        checklogin($_GET['username'],$_GET['password'],$key,$secret);
        die(0);
    }
echo "Login to get our secret";
echo "</html>";
?>

最初はレインボーテーブルとか使うのかなーと思っていましたが、ソースをよく見たらハッシュの下位4桁が指定されているだけなのですぐ生成できそうです。

php > for($i=0;$i<10000000;$i++){$plain='salt'.$i;$hashed=md5($plain);if(preg_match('/1337$/', $hashed)){echo $hashed.' '.$plain;break;}}
9fdf98f8019e1bc1e0b0cbe60d1e1337 salt369692

ということで /index.php?username=9fdf98f8019e1bc1e0b0cbe60d1e&password=salt369692 にアクセスすればフラグが出ます。

WhiteHat{92ab818618fee438a1ea3944b5940237975f2b1d}

以上です。

SECCON TOWER 参加記のようなもの

SECCON TOWER 解けませんでした。しかし画像処理や機械学習の経験が無くても、ググりながら OpenCV などを使って画像の分類ができたので、その経緯をメモしておきます。

先の 12/10-11 の SECCON Online に @hiww くんに誘われて Harekaze というチームで参加していました。ただ、 pwn はバイナリが読めないので手が出せず、他の問題も分からず。そのとき丁度 TOWER が行き詰まっているようだったので、やってみることにしました。

すでにプロ各位によりセマフォア信号で base32 でエンコードされているのではという推測が立っており、 @yuiki さんにより各信号のフレームも画像に抽出されている状態でした。

したがってこれらの画像をうまく分類することを考えます。 imagemagick で対象物周辺を切り出し、「opencv 画像 類似度」で検索、テンプレートマッチングを使うとマッチ度合いが取れそうなので試してみるも精度が出ず。

OpenCVのテンプレートマッチング | @knok blog

背景の写真がノイズになっているのかな、物体だけ取り出したい。そのためまずは背景を抽出することにしました。

python/OpenCVで複数の画像から背景だけを取り出す - BlankTar

わりと綺麗に抽出できたように思います。

f:id:tatarhy:20161216011034p:plain

この背景画像との差分を取って前景を抽出します。

Python3 OpenCV3で背景差分を求める - from umentu import stupid

f:id:tatarhy:20161216010805j:plain

うまくいかない……

ここでフレームを追うごとにカメラの位置が微妙にずれていっていることに気がつきます。そこで画像の位置合わせをすることに。以下の記事に行きつきます。

Image Alignment (ECC) in OpenCV ( C++ / Python ) | Learn OpenCV

f:id:tatarhy:20161216010842j:plain

よさそうです。ついでに2値化もしておきます。

Python OpenCV3で画像の画素値を二値化して出力 - from umentu import stupid

機械学習で使いそうなそれっぽい画像ができました。

f:id:tatarhy:20161214151206p:plain

で、これをどうやって分類するかですが、 kmeans を使えばよしなに分類してくれるような、と思ったのでこれを試してみます。

scikit-learn による最も基本的なクラスタリング分析 - Qiita

scikit-learn を使えば1行でできるとのこと。今回はクラスタの数も32だと分かっているのでこれでできそうです。そしてこれに突っ込む特徴量をどうするか考えます。ふつうはメッシュ特徴量とかを取るみたいなんですが、ためしに 8x8 に縮小してみたらいい感じにボケたので、これをそのまま使ってクラスタリングしてみます。

クラスタ毎にフォルダに分けます。

f:id:tatarhy:20161214165313p:plain

これは、結構いいんじゃないか?

いくつかのフォルダ内のサムネを目視で確認したところ、大方合っているように見えます。で、各クラスタとアルファベットの対応表ですが、時間が少なかったので @yuiki さんと手分けして手作業で作成しました。そしてデコード。

頼む、うまくいってくれ〜〜という気持ちでしたがパディングが合わずデコードできないままここで時間切れに。

f:id:tatarhy:20161214172852p:plain

なお2時半くらいから始めて途中睡眠も挟んで結局最後まで解けなかったので9時間以上かかっていることになります。手でやった方が早いんじゃ……とか思いながらコーディングしてたよね、うん。

後日談

因みに問題点が2点存在していたのでパディング詰めてもだめでした。1点はAが2つのクラスタに分類されたために、BとSが1つのクラスタに分類された点で、もう1点は急いでいたので対応表に4箇所誤りがあった点です。

f:id:tatarhy:20161215024557p:plain

したがってクラスタ数を33に増やしてクラスタリングを行い、心を落ち着かせて対応表を書いたところ、QRコードが表示されました!

f:id:tatarhy:20161215023123p:plain

感想

  • 画像処理や機械学習はほとんどやったことが無くてもググるとなんとかなったりする
  • ゴールが見えず手探りで、時間がかかりすぎた
  • いらない手順などを省略して短縮する余地はありそう
  • きれいに画像がフォルダ毎に分類できた一瞬とQRコードが出た一瞬は気分の高揚が得られる
  • 時間内に解きたかった

ただそもそもバイナリ力がなさすぎて pwn とか手付かずだったのでバイナリ勉強しなきゃなーという気持ちです。

pixiv冬インターンに参加しました

f:id:tatarhy:20151217181454j:plain

12月12日から13日にかけてpixiv冬インターンに参加してきました。バグと戦いました。

ssl.pixiv.net

選考

github.com

選考課題もバグとの戦いでした。

エントリー締切日にエントリーしたら選考課題締切までの猶予が3日ぐらいしかなくてヤバかったけど、 無事通過することができて、諦めずに提出することは大切だと思いました。

1日目

開発環境は開発サーバにsshでアクセス、GitHub上のpixivのスナップショットのレポジトリをクローンして作業、という感じでした。 pixivのエンジニアさんたちが実際に使っている環境とほとんど同じらしいです。 スナップショットも金曜日の昼にとりたてほやほやのものらしいです。 課題は issue にあげられていて、14個くらい、それぞれに難易度が1から5くらいで振られていました。

難易度1の課題から取り組んだのですが、 バグの全体像がいまいち掴めなくて思いの外手間取ってしまいました。 難易度1なのでもっとさっくり解決したかったけれど、これが現実か、、って感じでした。

なお昼食はスシとチキンとポテトという豪華な構成でした。 特にスシはステータス感があるのでつい呟きたくなります。

2日目

2日目は1日目のKPTを踏まえて、積極的にPR、わからなかったらメンターに質問していくことにしました。

PRのレビューでは、この関数は何をするもの?、とか、この条件式は必要?、といった質問、 この条件だとバグ治ってなくない?、とか、 json_decode は遅いので気軽に使わないで、などのツッコミ、 今回の課題的には脱出だけど、こうしておくともっといいかも、といったフォローなど いろいろな指摘をいただきました。

ひとつの課題から脱出するのも一筋縄ではいかなかったのですが、 普段レビューをしてもらえる機会が無いのでむしろ嬉しかったです。 また、指摘が的確なので納得するしかなかったし勉強になりました。 バイト等でPHPは触っていましたが作法しかり、バグの全体像を見通す眼力しかり、 まだまだスキルが足りていないと感じました。

f:id:tatarhy:20151217175744p:plain

レビューで100点貰えて ヨッシャ ってなったのがこの日のハイライト。

まとめ

  • pixiv のコードが触れる
  • pixivエンジニアの方々にレビューしてもらえる
  • 交通費、宿泊場所が提供されて、報酬まで出るので失うものはない
  • pixiv ノベルティがもらえる

バグとの戦いは大変だったけど、あのサイトのソースコードが丸々触れるって機会はなかなか無いし、 レビューやフォローもしてもらえるし、貴重な体験ができたかなと思います。 あとpixivにもバグはあるんだなっていうのがわかってそういう意味で親近感が少し湧きました。

pixivエンジニアの皆さんありがとうございました。

git challenge に参加しました

11/15 に mixi で行われた git challenge に参加しました.

alpha.mixi.co.jp

チームで git を使っているが,雑に使うやつのせいで,余計なファイルが入ったり,ブランチが無くなったりして困った,というシチュエーションの問題を解決する,コンテスト形式のチャレンジでした. 問題数は20問弱,問題のレベルは星の数で分けられており,星1~星3と星6(ラスボス,正解チーム無し)がありました.

f:id:tatarhy:20151117183550j:plain

結果

優勝してメダルを頂きました.チームメンバーに恵まれました(他のチームより1人多いという点も含め).

感想

私個人としては,星3の問題に取り掛かったけど解けなかったことが心残りでした.

この星3の問題,発想を転換して cherry-pick を使えば良いことが分かれば簡単に解けるという問題でした (rebase で頑張ってもできるらしい).

しかし,この発想に至れなかった. こういった問題は歴史がややこしくなっているので, 図を描いて状況を整理することが必要らしいです. また,git のしくみの理解があいまいで, reflog を使うと何が見られるんだったっけ? とか, 歴史を改変するとハッシュ値が変わってヤバいんだっけ? とか混乱してうまく方針を立てることができなかったことも原因になったと思います.

git の概念やしくみ理解していることが git 力の向上にもつながるそうなので, もう一度おさらいしたいと思いました.

ちなみに

一応焼き刃を付けておこうと思って急遽渋谷行きの列車の中で 入門git の後ろの章を眺めていて, まだ知らなかった便利なコマンドがあるんだなぁでも使わないかもなぁと思っていたら,適用できそうな問題があって, 面倒臭そうな事象が一発で解決できて,あーめちゃ便利ってなったことをここに報告します.

まとめ

  • 今まで使わなかった git コマンドを知ることができ,その便利さを体験することができた
  • git を使う上で足りていないスキルが分かった
  • git を雑に使うとヤバい

という訳で楽しかったし勉強になった git challenge でした. ありがとうございました.

入門git

入門git