「Gd」を含む日記 RSS

はてなキーワード: Gdとは

2011-10-25

不正利用撲滅の願いを込めて短縮 URL サービスドメイン一覧を晒す

URL 登録可能なサービスを運営しているとブラックリストに登録せざるを得ないような URL が登録される事もあるわけだけど、業者としてはそのブラックリストを逃れるために短縮 URL サービス不正利用してきたりします。


短縮 URL サービス側に不正報告をしても、三流サービスなんかはい対応してくれるのか分からない。自前の開発だったらそもそも 301 を返すような URL は一律エラーにする対応も取れるのだけど、いつもそうとは限らない。

というわけで、以前調べた時に生きていた短縮 URL サービスドメイン一覧を晒します。これをブラックリスト登録しておけば、大概は OK かと思います

.*.1sta.com
.*.24ex.com
.*.2fear.com
.*.2fortune.com
.*.2freedom.com
.*.2hell.com
.*.2savvy.com
.*.2truth.com
.*.2tunes.com
.*.alturl.com
.*.antiblog.com
.*.bigbig.com
.*.dealtap.com
.*.ebored.com
.*.echoz.com
.*.filetap.com
.*.funurl.com
.*.go2.jp
.*.guild.gs
.*.headplug.com
.*.hereweb.com
.*.hitart.com
.*.jpn.ch
.*.mirrorz.com
.*.office.vg
.*.soho.bz
.*.tn.st
.*.vze.com
007.sh
0oo.be
0rz.tw
1-0x.com
1-9.jp
1bps.biz
1cc.jp
1huji.com
2ch.to
2ch2.net
2z2.biz
34vv.net
3w.to
4649.st
5jp.net
690.jp
7pi.jp
99q.info
a.rrweb.jp
a6r.org
a8-affili.info
ac.la
adop.jp
akb.cx
an.to
bit.ly
c.ly
c23.biz
d99.biz
dwarfurl.com
e-safar.com
eeg.jp
ez.cm
fw.iclub.to
g.nu
gmaru.be
goo.gl
hyu.jp
icanhaz.com
ie.to
is.gd
j.mp
j2url.com
jpn.ch
linkbee.com
linkoop.com
masl.to
mf1.jp
mixi.bz
mj1.biz
mo-v.jp
notlong.com
nsfw.in
os7.biz
p.tl
php5.jp
php6.jp
piurl.com
qrl.jp
qurl.com
qurlyq.com
r1.gs
rurl.jp
s78.biz
scut.ly
sfurl.biz
shorterurls.com
simurl.com
snurl.com
ss.st
su.pr
t.co
tens0.net
tiny-url.org
tiny.cc
tinyurl.com
to.cx
to1.bz
tok2.com
tr.im
traceurl.com
twurl.nl
ulr.jp
ur1.jp
url.ms
urlenco.de
urlz.jp
urx.nu
utun.jp
wb2.biz
ww36.com
www.estyle.ne.jp
www1.to
www3.to
xfs.jp
xtw.me
xurl.jp
yutn.me
z-x.in
zz.tc

※色々理由を付けたりしてますが、結局の所、世の中にはこんなにいっぱい短縮 URL サービスがあるんだぜ!という驚きを共有したいだけ、かも。

2010-11-24

http://anond.hatelabo.jp/20101124195429

いや、そういうのを名前で見るんだよ

履歴書の手書き文字の形で応募者の人格を読まれるんだから



@どんな顔か @どんな名前か @性別は何か @年齢は何歳か @生まれ育った住所はどこか @生まれ育った住所はどのような所得水準の人間が住む地域

@出身高校はどこか、難関中高一貫校国立かトップ公立か無名校か  @出身大学はどこか、どのような入試形態で入ったか

自己PR履歴書の文体からどんな性格と思考を持っているか @スポーツは何をやっていたか、団体競技か個人競技か @趣味は何か、アウトドア的かインドア的か

筆記試験で基礎学力はどのくらいか @GDコミュニケーション能力はどうか @面接してどんな印象の人物か 


生まれ育ちは大事だよ。会社ボランティアじゃないから傷物の人間は排除しなければならない

2010-03-07

就職活動中に思ったこと

唯一、新卒就職活動してた会社から希望してた職種で内定もらえた。

とりあえず就職活動が終わったことになるので思ったことを偉そうに書いてみる。

就活ビジネスについて

就活マニュアル本とかいろいろあるじゃないですか?SPI対策本とかも含めて。

あれって社会に悪い影響を与えてるんじゃない?

SPI対策本を例に挙げると、SPIはたぶんその人の思考能力みたいな知力を見るもんなんでしょ?

「知力が高い人」と「知力の低い人」をそれぞれの企業の基準で見るためのテストであるはずが、対策本によって

「対策をした知力の低い人、知力が高い人」と「対策してない知力が低い人」になるわけですよね。

「対策をした知力の低い人」を量産して世の中に送り込んで世の中良くなると思ってるの?印税さえ入ってくれば良いの?

就活について

就活情報サイト主催就活セミナーに参加したけど、一部の人間が新興宗教の熱心な信者みたいで気持ち悪かった。

GDはやたら主導権を握り、自分意見を通そうとする人が面倒だった。しかも頭いい大学うまい具合にいなしてたら女の子が俺のアホな意見に賛同し始めた。あの娘たち絶対俺に気があった。

今回のセミナー感想をいう場は、お前絶対にそんな事思ってないだろ!って突っ込みたくなるような事をいういう人や、棒読みで模範解答を読むような感想を述べる人ばかり。しかも頭いい大学

あんなんが大手にいっちゃうのかなーってそのときは思った。

主催者側の司会進行も学生就活モードにするには完璧ファシリテーションだった。けど、なんか違和感があった。

志望する企業のプレセミナーには結局その就活モードでいってみた。つまらなかったし、就活って大変だと思った。

その2ヵ月後に受けた1次選考の最初に「リラックスして下さい、一緒に働く仲間を見つけましょう」みたいな事を司会の人が言っててハッとした。

やっぱそうだよなと思って、誘われた合コンに行く程度の緊張感と期待感を持って集団面接に望んだ。名物社長のムチャぶりをユーモア混じりに返したりして楽しめた。

結果は1次通過。あの会場ではダントツでしたと言われた。

2次もそのままの調子でいった。むしろダントツと言われたことによって少々調子にノっていった。あたりまえだけど敬語は普段程度には使ったけど態度が少々デカかった。

でも、エントリーシート履歴書に書いてあることは自分からは言わないというルールは作った。

こんな資格あります!とかこんな賞とりました!とか初対面で言ったら嫌なヤツだし。しゃべるのが好きっていってそこから話を広げた。

自信満々に振舞ったり、謙虚になったりと初対面の人に対する普通の対応。

ちなみに資格はその職種に必須の車の免許すらないし、賞も部活のが少々とリーダー経験あるぐらい。

筆記試験はその会社オリジナル教養試験IQテスト教養試験はその場でトップだったらしい。

選考会後に懇親会もあったりで楽しかった。最初にとなりだった娘と途中で俺のとなりに来た娘は絶対俺に惚れてた。

俺は運良くほとんど苦しまずに内定がもらえたからいいけど、就活という言葉に乗せられてわざわざ苦しい思いをしてる人が多い気がする。一年以上苦しみ続けていまだに内定が無い後輩もいる。

もしかしたら就活なんて事をあまり意識せずに普通に、もしくは楽しんで望めば就活モードよりいい印象を与えられるかもしれないので、いま就職活動中や今後就職活動に望む学生の人はそんなやり方もあって、うまいこといった人間もいるんだと頭の片隅にでも入れといて下さい。

最後になりましたが就活に群がる連中爆発しろ

2009-10-24

文系内定を取りに行く方法※ただし新卒に限る

■追記

なんだか社畜選別方法だとか言われていますが、そうなのかもしれません。

ただ以下のことが自己分析ののちに実体験として語れる学生は入社してから伸びることが多いです。タイトルにもありますがこれは新卒文系内定を取るための方法です。文系新卒の8割はモラトリアムを満喫しただけで単位のための勉学しかしていません。その子たちが急に就職活動に挑むとなった場合大体玉砕することになります。ですがその子たちが空っぽなのかと言われればそんなことはないですし、当然モラトリアム中という18~20歳ぐらいまでの間に体験、経験したことはその人の人間的成長を語る上では外せない時期となっています。だからこそそこをうまく就職活動で見せられるような人が欲しいのです。わざわざエントリーシートでこの子はどんな子なんだろう、なんて思いを馳せるのは無理なので。(追記終了)




http://anond.hatelabo.jp/20091024224652

全員が全員自分成功体験談を書くからどれを信じたらいいかわからないということが多いので。

ちなみにわたしは人材コンサル→大手人事部→大手人事部の経歴。人事としての経歴と転職活動、就職活動を通しての話です。

わたしは傾向としてスジが通っている人を採用する傾向にあるので、論理重視ですが、参考までに。

前提

マーチクラス以上(自分大学マーチクラスギリギリアウトかなーみたいな人はたぶんアウト。)

この辺の学歴がないとエントリー時点でサクッと学歴足切りがあるので。

こればっかりはもうどうすることもできません。

エントリー

3業種30社と言われますが妥当だと思います。

最初のうちはマスコミから始まりますが受けておきましょう。すべて練習と割り切って受ければいいです。


自己PR

多くの就職活動本に書いてあることと重複してしまいますが、必要なのはあなたがどんな人間か浮かび上がらせることです。

あれも話したい、これも話したいとか思わずにまずは自分の中でのキラーコンテンツを見つけてください。一般的にいえば、部活サークルバイトゼミです。

学業をがんばったアピールしても専門的な内容になればなるほど、面接面接官が聞いていて楽しくないので落ちることが多いです。

重要なのは

  • 何を(1)、何のために(2)頑張り、何を(3)学んだのか?です。

(1)ここはシンプルですね。読んでいる人の心をつかむために奇をてらう必要はありません。シンプルに前述したものを中心に大学生活4年間を思い出しましょう。

(2)ここはそれなりに大事です。バイトお金のためにとか言ってしまうとおそらく事実でしょうが、元も子もありません。ある種自己犠牲的な目的だと偉いね、という感じになります。

例・みんなの役に立ちたかった。

(3)ここが重要です。正直(1)~(2)を話す人が多いのですが、重要なのは(3)です。結局キミがどう成長したのか、どんな価値観を得たのかという部分を知りたいのです。

例・(便宜的にざっくりしていますが)○○をすることで人に感謝される喜びを知り、そういったことに興味を持つようになりました。→ここは充実感を持つようになった。ぐらいだと嫌味になりません。


このあたりが抑えてあればまずはOKです。

これだけ抑えるだけで同じ大学ライバルが10人いたとしたら2人には勝てます。


志望動機

ここも、もちろん重要です。ここは他人と差をつけるチャンスです。

自己PR転用してまずは志望動機にしてください。転用するのは

  • ○○をすることで
  • 人に感謝される喜び

この2点のうちどちらか、もしくは両方です。

前者はシンプルな話になるので強いですね。○○の部分が会社の事業内容につながっていればいいだけです。

後者の方は少し工夫しましょう。人に感謝されることがよかった→人の役に立ちたい→自分が興味のあることを通じて役に立ちたい→御社の事業内容を通じて役に立ちたい。という変換ですね。ここは自分の興味と事業内容をどうつなげるかが大事ですが、大手企業だったら自分の生活とつなげて興味を持ったぐらいは言えるようになってください。ニッチ産業であったり、マイナーな事業の場合は、その産業をほめて貢献したいと言いましょう。


もちろんこれだけではだめです。

これは業界志望動機でしかないので。

ただしここはあまりウソで塗り固めても内定を取るだけで働いてからギャップを感じたり、本当に向いていない業界の可能性もありますのでホドホドに。


ここにさらに御社じゃないとだめなんです。という要素を足しましょう。

このあたりは同業の中での強みをほめるのが鉄則です。業界ナンバー2だろうがナンバー5だろうがなんか強みがあるハズです。そこに惹かれたというのがベストです。ただ、やっぱり大した強みのない会社もあります。残念ですがその場合は企業理念を引っ張ってきましょう。

例・御社の○○という社訓や、創業者の△△という理念共感したため御社を志望しました。


こうすることで、あなたの大学生活からどうしてこの会社に興味を持ったのかまでがつながります。

このメリットは後述しますが、今はつなげるとイイということを覚えてください。


これで残った7人の中からさらに2人勝てます。

エントリーシート

自己PRと志望動機が前述したようにあればなんの問題もありません。趣味・特技の欄はアイスブレイク的なもので使ったり、面接官にちょっと興味を惹かせるためのものなのでそこを一生懸命書いてメインにしないでくださいね。

よく、読書映画鑑賞音楽鑑賞はまずいと思っている人もいますが別にまずくはないです。逆に無難に書くと面接官になんとなく突っ込まれたときに痛い目を見るので正直に書くか、聞かれた時のために全力でねつ造しておきましょう。読書なら最近ベストセラーで十分です。その作家過去の作品5作品程度抑えておけばなおよしといったレベルです。


筆記試験(SPメインですが)

わたしが前提であげた学歴の人なら国語は問題ないでしょう。算数(あえて算数と言います)に関しては私大で数学を捨てて受験した方は問題集1冊買うぐらいの投資はしておきましょう。あと筆記試験というのはいろんな企業でやっています。早めに就職活動をしておくと同じ問題にめぐりあうこともありますし、練習感覚でどうでもいい企業のを受けるというのもありです。

重要なのは性格を問うアンケートです。

さすがにこのあたりは多くの本でも書いてありますが、希望する業種において必要な性格になりそうな答えを意識してください。

ただし日本企業の場合精神的なタフさはマスト条件です。


一人ぐらい馬鹿正直な性格を申告してしまうので残りライバルは5人です。


面接(集団)

どこかのダイアリーにもありましたが、ここで恥ずかしがったり格好つけてはいけません。必死さを出す必要はありませんが、まじめにやりましょう。

ここは与えられるのは自己PRを1分と志望動機30秒レベルでしょう。あとはよくある質問です。

ここで自己PRと志望動機をつなげておくとイチから説明することもなくスムーズに話せますし、当然面接官の頭にも入りやすいので好印象で、「コイツは論理力がある」と思われやすいです。

よくある質問なんていうのは、学生時代頑張ったことだとかそのレベルです。自己PRをさらに強化する時間です。余裕があればだからこそ御社でみたいなことを言っておきましょう。いやらしいですが面接なんていうのはそんな場です。


最後の質疑応答は個人的にはあまり重要視していませんが、まあ当たり障りのないことを聞くか、面接官の当時の志望動機とか聞いてみるのもいいですね。

悪い意味で印象に残っているのは、もう一度就職活動をするとしたら、御社を受けますか?と聞かれたことですかね。あたりまえだろ。

良い意味印象の質問だと、わたしの話はわかりやすかったですか?という質問は嫌いじゃないです。採用に関わるのであまり確信的なことを言えないのですが軽くフィードバックをしてあげました。


まあこれぐらいですが、集団面接ということで暴走して話しすぎる人は落とされやすいので指定された時間意識しておくこと。自己PRに関してはこれから何十回ということもあるので30秒バージョン、1分バージョン、2分バージョンぐらいは用意しておきましょう。


暴走して一人、テンパって一人計2人ぐらい脱落するんじゃないでしょうか。


GD(またはグループワーク)

初めに言っておきますが、所詮学生GDです。すごいビジネスにつながる意見を求めているわけではありませんし、変な爪痕を残そうとするのはやめた方がいいです。

みたいのはこの子が会社に入ったらどんな感じで発言をするんだろう。会議におけるポジションを見るだけです。

欲しい人材っていうのは

こんな感じです。どれが自信ありますか?その自信のある能力をすべてのGDで発揮できますか?

ですが、誰にでもある程度、積極的に現状分析ができ、役割を意識できる人間であることをアピールできる方法があります。


議長です。

議長をやれば、別に正しい意見は言わなくていいんです。話を聞きながらステップ毎にいったん話をまとめるだけです。ですが要所でまとめるだけでも印象はとてもいいです。さらにメリットとしてはGDでは最後に発表するケースが多々ありますが、往々にしてプレゼンターは議長になります。立候補しても納得度が高く信任されるのでお得です。どうですか?議長さえしっかりやればGDなんて怖くもなんともありません。


議長になりたい場合これは戦争です。事前にGDという告知はしてあると思うのでそこは上手に立ち回りましょう。

最初に待合所にグループで通されたときから仕掛けるべきです。まずは社交的に全員と話すこと。大学名はサラっと言い、サークルでのポジションでちょっとしたリーダーをやっていた、バイトリーダーをやっていたみたいなことをウソでもいいので言えばなんとなくコイツしっかりしてると思われます。そしていざGDが始まったときに、なにがあっても一番最初に口を開くことです。GDの最初なんてのは役割決めですから。「じゃあ僕、わたし議長やろうか、そういう仕事慣れてるし」と一言言えば反論はそう来ません。来た場合は、時計を気にして「じゃあキミに任せるよ、他の役割も決めよう」と言えば大人の対応です。GDでの発言になんとなくの権威が生まれてあわよくば発表者にはなれます。


ここまで来ると同じ大学ライバルはあと3人ってところですかね。



人事面接(最終手前面接)

ここで人事が知りたいのは、結局自己PR志望動機です。それをじっくりと聞くだけの場です。まあきっとしっかり作りこんでいるでしょうし、このころには他の会社でもいろいろトライアンドエラーをして立派なものになっているでしょう。そうした場合、他のライバルの連動のない自己PR志望動機に対して圧倒的に強いので大丈夫です。あとは自己PRの引き出しを増やしておきましょう。そこについて突っ込まれたときにどう論理的に返すかがカギです。なんでそう思ったのか。なんでそれをしたのか。起こした失敗は?(失敗に関して失敗を本当に語らないでください、聞きたいのは二度と失敗をしないようになにを心掛けているのかですから。)レベルは考えておきましょう。

あとは第一志望の理由ですね。業界トップじゃない会社であればあるほど聞いてきます。間違っても第二志望とか言わないでくださいね。志望理由と一緒に時にはウソをつけるかというのも地味に見ていますので。他のエントリーしている企業は他業種2社、同業2社ぐらいが無難です。同業2社の出し方は難しいですが御社が第一志望である理由と、同業の会社は御社がダメだったときと言えば基本OK。しつこく他の企業を受けている理由を聞かれた場合には実際同業の会社のいいとこを言ったうえで、でも一番は御社です。という結論へ。もし本当に持ち駒が0のときは、ウソをついてください。正直0は他の人事が見向きもしなかったという証以上の効果はありません。昔泣きだした女の子がいましたが落としました。

まあここまで出来ていれば大丈夫でしょうが、付け加えておくことと言えば、勉学をちゃんとやっていたかどうかです。一応会社ですからちゃんとそこも確認します。ゼミで一番調べたことの話をすればいいです。もしくは営業志望ならバリバリ体育会を自認するでもいいですが。


さあ後は最終面接です。きっとライバルはあなたとあと一人となっています。


最終面接

一応人事面接で前述レベルでしっかり出来た人は人事からもプッシュしますが、多くは運ですね。

ワンマン社長みたいな会社では対策できませんが、大手の場合は安全枠というか、まあ悪く言えば社長取締役ダメと言っても人事的に高評価な人を取ってバランスを気をつけるのでしっかり話せれば大丈夫でしょう。



最後に

なんでこんなに一生懸命書いたのか自分でもわかりません。

本を書いている人の内容が薄いくせにいっぱい儲かっているのが悔しかったんだと思います。

面接系の本は学校にあるはずなので、筆記用と業界分析用の本だけ買えばいいですよ。

それでは皆様のご武運とエントリーお待ちしております!

2009-10-04

グーグルマップ壁紙にしてみる

10/18 改訂



グーグルマップ航空写真をつなげて一枚にするスクリプト

なお、取得した画像著作権グーグル他各社が保持しています。

ご利用は計画的に私的範囲でどうぞご利用ください。

#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use LWP::UserAgent;
use GD;

my $cmdline = join(" ", $0, @ARGV);
my $usage = "usage: $0 -sx=116423 -sy=51603 -ex=116426 -ey=51605 -dx=4 -dy=3 -z=17 -size=300 -get=30 -dir=cache -output=output.jpg -nodebug";
my ($sx, $sy) = (0, 0);
my ($ex, $ey) = (0, 0);
my ($dx, $dy) = (4, 3);
my $z = 17;
my $size = 300;
my $get = 30;
my $dir = "cache";
my $output = "output.jpg";
my $debug = 0;
GetOptions("sx=i" => \$sx, "sy=i" => \$sy,
	   "ex=i" => \$ex, "ey=i" => \$ey,
	   "dx=i" => \$dx, "dy=i" => \$dy,
	   "z=i" => \$z,
	   "size=i" => \$size, "get=i" => $get,
	   "dir=s" => \$dir, "output=s" => \$output,
	   "debug!" => \$debug) or die "$usage\nDied";
if ($ex == 0) {
    $ex = $sx + $dx;
} else {
    $ex++;
    $dx = $ex - $sx;
}
if ($ey == 0) {
    $ey = $sy + $dy;
} else {
    $ey++;
    $dy = $ey - $sy;
}
$sx>0 and $dx>0 and $sy>0 and $dy>0 and $z>0 and $dir and $output
    or die "$usage\nBad arguments";
$dx*$dy > $size and die "Getting too large.";

$debug and print "debug: mkdir $dir\n";
mkdir $dir;
-d $dir or die "can't make dir $dir: $!";

my $base = sprintf("http://khm%d.google.co.jp/kh/v=46&z=%d", int(rand(4)), $z);
my $ua = LWP::UserAgent->new;
printf "now get %d images...\n", $dx*$dy;
for (my $x=$sx; $x < $ex; $x++) {
    for (my $y=$sy; $y < $ey; $y++) {
	my $file = sprintf("%s/%02dz%06dx%06d.jpg", $dir, $z, $x, $y);
	$debug and print "debug: check of $file\n";
	-s $file and next;
	--$get < 0 and last;
	my $req = HTTP::Request->new(GET=>+"$base&x=$x&y=$y");
	$debug and print "debug: fetch from ".$req->uri."\n";
	my $res = $ua->request($req);
	unless ($res->is_success) {
	    print "fail fetch from $file: ", $res->status_line, "\n";
	    next;
	}
	if (open(my $fh, ">", $file)) {
	    $debug and print "debug: write of $file\n";
	    binmode $fh;
	    print $fh $res->content;
	    close $fh;
	} else {
	    print "fail open in $file: $!\n";
	}
    }
}
$get < 0 and print "reach the getting limit, skip after all.\n";

printf "creating %dX%d image...\n", 256*$dx, 256*$dy;
my $image = new GD::Image(256*$dx, 256*$dy);
for (my $x=$sx; $x < $ex; $x++) {
    for (my $y=$sy; $y < $ey; $y++) {
	my $file = sprintf("%s/%02dz%06dx%06d.jpg", $dir, $z, $x, $y);
	$debug and print "debug: check of $file\n";
	-s $file or next;
	$debug and print "debug: read of $file\n";
	my $part = GD::Image->newFromJpeg($file);
	$debug and print "debug: image copy\n";
	$image->copy($part, 256*($x-$sx), 256*($y-$sy), 0, 0, 256, 256);
    }
}
#$image->string(gdSmallFont, 0, 0, $cmdline, $image->colorAllocate(255, 255, 255));
open(my $fh, ">", $output) or die "fail open $output: $!";
$debug and print "debug: write of $output\n";
binmode $fh;
print $fh $image->jpeg();
close $fh;

例えば秋葉原とか

perl gmwall.pl -sx=116423 -sy=51603 -ex=116427 -ey=51606

駅だけとか

perl gmwall.pl -sx=465701 -sy=206420 -ex=465705 -ey=206423 -z=19

使う数値はfirebugなどで拾ってください。

2009-05-10

就職活動が終わったよ

情報系のFラン大学生だけど、就職活動が終わった。

突然暇になったので、所感でも書いてみたいと思う。



一般的な就職活動の流れ

自己分析業界研究企業研究

説明会

選考

内定



こんな流れのようだ。

僕は情報系ということもあって、初めからIT業界を志望していた。だから業界研究はせず企業研究だけ行った。

自己分析も特にやらなかった。だってESにしろ面接にしろ尋ねられたことに素直に(ちょっとした脚色は必要かもしれないけど)答えればいいだけだから。

ちなみに僕はサークル部活もしていないので、アルバイト学業のことしか話題にできなった。この二つだけでも十分だと思う。



実際にどうしたか

ものの本によると就職活動は3年生の夏ごろから始まるらしい。いろんな企業さんがインターンシップを実施しているからだ。

僕もインターンシップに参加するかと思い立ち、申し込んだ。だが、途中で面倒になって投げ出した。なぜかと訊かれても本当に面倒だったからとしか言えない。

芽生えかけていた就職活動へのやる気は霧散して、僕が就職活動を再開するのは11月頃だった。

メーラーを見るとリクナビ2010に登録したのは2008年11月6日6月サイトオープンしていることを考えると、だいぶ登録するのは遅かったのかもしれない。

それから説明会に参加し始めた。

有力なIT系企業東京に集中している。僕は地方に住んでいるので、説明会に参加する度に上京することになった。交通費・宿泊費・食費は合計で10万を軽く超えたと思う。

志望している企業は3~5社あった。そこの説明会に参加するときの空いた時間によさげな企業の説明会を突っ込んで、合計で20社ぐらいの説明会に参加した。



選考が始まると筆記試験が始まる。

筆記試験の対策は1月ごろから始めた。参考書を買ったり借りたりして問題数をこなした。

僕が実際に受けたのはSPI,テストセンター,CAB,Web-CABの四種類だけだった。

テストセンターが一番簡単(使い回しもできる)で、Web-CABが一番難しかったと思う。とあるデー子で結果を教えてもらったのだが、6~7割ぐらいしか正解していなかった。だけど、それぐらい取れていれば十分だとも言われた。



筆記試験を通過したら、面接GDが行われる。

これは上でも書いたように素直に自分意見を相手に伝えただけ。少しかっこつけたりはしたけれど、捏造はしなかった。

自分のやり方が絶対に正しいとは思わないけれど、面接官に好かれようとする受け答えよりも、正直なほうがぼろが出ないんじゃないかと思う。



そして面接が何回か行われて、最終面接を通過したら内々定が出る。

内々定がでると就職活動が終わる。僕の場合はGW直前に本命の最終面接があり、GW明けに内々定がもらえた。



就職活動の結果



中々良い感じで就職活動ができたんじゃないだろうか。

すごい人はもっとすごいけど、駄目な人と比べたらこれで上出来だと思う。

本命企業内々定がもらえたことが一番良かった。



これから就職活動をする人へ

IT業界を目指す人はとにかく企業研究が大事だと思う。

事業内容・福利厚生労働環境あたりはきちんと調べたほうがいいと思う。個人的には月200時間残業するのが当たり前なところには行きたくないし、興味の持てない仕事もしたくない。

それと何事も早め早めが大事。

面接も筆記も早めに取り組んでおけば気持に余裕が持てるんじゃないかな。



最後に面接で一番大事だと思うことを書いておく。

それは、運。

自分以上に面接対策に努力してきた知人がいるけれど、面接で落ちまくっている。

知人が僕より劣っているとは思えない。むしろ入退室のマナーや滑らかな受け答えを見ると、僕より数段すぐれている。

彼と僕の間に差があるとしたら・・・それは運なんじゃないかな。

2009-03-11

http://anond.hatelabo.jp/20090311172012

imox の検索結果 約 27,900 件中 1 - 10 件目 (0.08 秒)

http://www.google.com/search?q=imox&amp;hl=ja&amp;sourceid=gd&amp;rlz=1Q1GGLD_jaJP307JP309

案外あるなw

2009-01-22

理系GDにおいてとるべき態度

http://d.hatena.ne.jp/takerunba/20090116/p2

GDで「この問題は不快なので答えたくありません」って言っちゃダメなのだろうか。

借りてきた猫のように、言われたとおりの範囲で考えることしか許されないのだろうか。

新人だからそれで十分、というのはわからなくもないが、そういうのって

骨も牙も抜かれた人材

という表現が適切な感じがする。その状態を強制しておいて、ディスカッションが盛り上がるだろうか。


シャイ理系がまず克服しなければいけないのはこの3つ。

http://blogs.yahoo.co.jp/engineer_ryuseigun/33131960.html

前提を素直に受け止めすぎる

http://blogs.yahoo.co.jp/engineer_ryuseigun/33652656.html

配慮より効率

http://blogs.yahoo.co.jp/engineer_ryuseigun/39154295.html

反省より分析



真の理系なら、もっとこだわっていくべき

http://blogs.yahoo.co.jp/engineer_ryuseigun/38049525.html

前提にこだわりすぎて台無し

http://blogs.yahoo.co.jp/engineer_ryuseigun/34552924.html

独自の視点で独自の真実を追求する

http://blogs.yahoo.co.jp/engineer_ryuseigun/32924661.html

自分で問題をややこしくする

2009-01-21

タケルンバグループディスカッション問題リンク収集

(あるいははてなにおいて戦線が拡大し収束不能になる過程の記録。)

悪いのは誰? - ある無人島漂流の物語 - タケルンバ卿日記

卿@twitter(順不同)

ま、これだけみんなが何かしら引っかかっているということは、それだけ良問ということなんだろうな。エクセレンツ。



@_temaki_ あ、そこか。あれは違うんだよ。話を聞いた女の子(研修した子)がそう言ってたんだよ。「感情論でおしたんだけど、ダメでしたー」って。俺が感情論って判断したわけじゃなす。



@y_arim (つづき)そういう考え方を開陳するなという発想には賛同しかねる。表現者として自殺行為だし、表現の自由だべや。もっとも、そんなレベルの話じゃないというのが率直な印象。単なる思考実験だよ。深くとられても困る。深くとるならお好きにどーぞって話だべや。



@y_arim 答えを出して、正しいかどうかを検討する場ではないからセクハラではないよ。絶対的に正しい正答はないという状況下でないとGDは成立しない。価値観が問われるのは確かだが、ビジネスではもっと厳しい選択を迫られるのが常なので、これでハラスメントなら働けないよ。



@y_arim だから単なる思考実験なのよ。「悪い」という定義を曖昧にするから、そこからGDがはじまる。価値観がぶつかる。まとまればそれでよし。まとまらなければ、どこかで多数決になる。多数決になれば、少数派が満足しないケースもある。そういう経験も含めてのGD。深く考えなくていい。



@taitoku そういう話っていいんですよね、GDとしては。ギッシリ人がのった救命ボートの中に、伝染病の患者が出た。どうする? とか。こういう倫理観が問われる出題を嫌がる人はいるけど、タブーだからこそ、思考訓練にはいい面もあるわけで。



@Yoi ああ、あるでしょうね。実際、その研修時、論理的な回答をした男性に女性陣はd nbkだったそうですw

dnbk=どんびき、らしい。



@_temaki_ うん。だからあれは同性のみのGDでしか使っちゃいけない論題だと思ってるよ。異性がいる環境では俺は使いたくない。ただ、思考実験として、自分だったらどうかって考えるのは悪いことではないと思うな。その意見を言うかどうかは別としてね。



@_temaki_ 現実行われた研修の話だし、昔からこの手のGDは他の場所でも行われてきたんだから現実としてしょうがないっしょ。ただ、それと、その現状を良いと思うかは別論点なんだけどね。企業のリアルな現場には、もっとひどいのがあるはずだよ。俺はそういうのが嫌だからフリーなわけで。



@y_arim それはあなたの妥当性であって、俺がどうこう言う筋合いではない。この件に関してはあらゆる意見が正しい。それ以上でも以下でもない。俺は俺以外の意見を尊重する。但し俺の意見も同様に正しい。意見の間に順位付けなどないし、人の意見に意見を挟みたくない。



@yoppa0516 そうそう。俺もそう思ってたの。こういう喧々諤々できる設問がいいのにね。価値観がバラバラだから、思考実験にいいのに。なかなかおもしろいリアクションだと思った。これは新発見。



@Yoi 思考実験とはいえ、身に置き換えて考えやすいからこそ、痛みを伴うのかもしれませんね。想像上の世界とか、思考や論理ではなくて、自分の身に置き換えて考えやすいのかも。



@Yoi そうですね。共通の答えを導くプロセスの学習と、ほどほどの妥協の必要性とか。そういう社会性を身に着けるのに適しているかと思います。



@Harashooter 講師の導き方次第で、如何様にも教訓を学べる設問ですよ。論理的思考を学べますし、議論がまとまらないことから価値観の多様性も学べますし、性的な話に対する嫌悪感とか、結論を出さなければいけない場面において、納得のいかない結論になるケースを理解するとか。



@_temaki_ そうなんだけど、それを会社の研修という強制参加の場でどうよって反発はようわかる。わかるが、それは俺のせいじゃないw 第一、俺が講師か研修担当者なら、この論題選ばんよ。



@threelz つか、研修受けた人の話聞く限り、そういう研修なんよ。まとまらないことを学ぶ研修というか。あるいは強引にまとめることで、まとめたかに見えて、実はバラバラになる体験をしたりとか。



@satokom そうなんですよ。だからこの研修もグループごとに結論が違ったり、グループで出た結論に対し、どれだけの人間が反発を感じるかってテストでもあるんです。集団の決定だなんて、こんなもんなんだみたいな。社会性のテストでもありますね。

トラックバックしてるエントリからいくつか

※以下流れを大づかみにつかむための説明文なので、詳細は本文を参照してくださいです。


無人島のこと - はてな読み

論理的思考と説得の技術を試す機会だ、という考え方は『それはそれでひとつの考え方なのでしょう。』としながら

女性感情論を、ムリヤリ数の力と、論理で押し切ったようですな。』という卿の発言を批判。

会社の行った研修に対しても『低俗心理テストもどき』として短く批判。



悪いのは性根の腐った似非貴族に決まってるだろ。 - 消毒しましょ!

卿がエントリで示した考え方に対する罵倒

『「関係を迫った男が許せない」、「関係を持つことを条件に、船を直すだなんてヒドイ!」という極めて当たり前の道徳を、平気で「女性感情論」と切って捨てることの出来る非道さを見るだけでも、このバカが如何に拙劣人間性しか持ち合わせていないことは即座に理解できよう。』



そもそも善悪の判断つけるべき話か? - NC-15

感想自分が体験した類似のGDの話と卿の回答対する批判。

「川を渡る女」の改編であると指摘。

『まあ、こういうしょうもないディスカッションって新人研修でやるところあるよな。俺が最初にこの業界で潜り込んだ会社でもやってた。正直アホらしかったがな。』

『ちなみに研修のときの回答は、「ただ、Lさんが金槌持ってSかBの後頭部ぶっ叩いて気絶させて有り金と船パクって渡っちまったら万事すべて解決するだけの話じゃね?」と。研修担当産業カウンセラーから「あなたはめちゃくちゃ反社会的で歪んでる。」と言われたけどね。アホらしくて付き合う気にもなれない。』

『そもそもさ、このくだりもかなり偏見が入ってるわけで。元々、その女性たちの意見を「感情論」と片付ける発想と、「金出せばやらせてくれるからいーじゃねーか」というのを論理と考える発想ってさ。それこそ以前炎上した原因そのまんまの話なわけで』



「○○についてグループで一番を決めてください」って何がしたいかわからない - 遥か彼方の彼方から

価値観を問題にするのであれば一つの結論を出せるはずがないので、ディスカッション意味がよくわからない、という批判。



タケルンバ卿は「おじいさん」になってほしくない - 魔王14歳の幸福な電波

卿のtwitterでの発言に対し批判に対し傍観者になるべきでないと批判。

(後に卿は該当の発言は仕事に対するものだったと弁明。)

id:takerunba これだけブコメがついて、誰一人、個人的な仕事についての発言という可能性を考えない件について。何でもかんでもブログのことについて発言してると思ったら大間違いあるよ。



『ある無人島漂流の物語』がセクシズムである理由 - ロココの足袋

このテーマGDをセットした企業を『題材提示の時点で既に性差別存在している』として批判。

『もし欧米企業で同じ研修が行われたら、担当責任者の首が飛ぶ問題になりかねません』日本企業性差別へのデリカシーのなさ等を批判。



論題の意図と改変の意味 - 地を這う難破船

無人島」は「「川を渡る女」の『「性的な局面においてその人の大事にするものがわかる」という認識に基づく改変です』と指摘。

『その発想が新入社員研修において持ち出されることがセクシャルハラスメントでないなら、セクシャルハラスメントという概念が何であるかさっぱりわからない。』と批判



F's Garage:この話はチェーンメール的な悪魔の話

『そう。この設問は、それそのものが理不尽なんだろう。』としながら一連の流れが面白いという反応。

『この話では誰が悪いという結論はどうでもよくて、その過程の反応にこそ価値がある。』としている。

話の論点は『「答えの出ない理不尽な状況下に、個人とビジネスどちらを優先するか?」』にあるのではないかという考察

GDの議題に対する個人的回答。



ゲス問題なGDを切り抜ける方法と、ゲス話にイライラしないですむライフハック - 春巻たべた

問題文を読み変え再設定することで上手く切り抜ける方法を提示。

その後、『こういった鬱展開に揺らがないためにはどうすればいいのか?』という問題に対し、独特の考え方が続く。


『そしてもちろん僕は僕自身の宗教を打ち立てる道を選んだ。大学一年の春のことである。』

『僕の宗教に神はなく、ただ僕と僕以外がいるのみである。世界に不幸があるのはつまるところ僕が世界を救わなかったからだ。』



id:takerunbaは擁護可能かw - 幸せの鐘g(r

twitterでのy_arimとのやり取り提示しながら卿の意図の推測と卿への批判。



2009-01-21 - planet カラダン

ビジネスの場、それも一企業の内部では、多くの場合で前提状況そのものを問うことは禁じられている。

いや、禁じられてなどいないかのようになってるけど、誰も歓迎はしない』として

この議題は差別的なジェンダー規範内面化させものではないかのではないかとして批判。



研修という聖域 あるいはモラトリアムの憂鬱 - 背後からハミング

『それにしてもid:takerunbaさんは少し叩かれすぎだと思います。』卿を条件付き擁護。

研修アウトソーシングされそこで企業日常業務では到底ありえないような行為が公然と行われるケースが多くあることを指摘。企業研修が「聖域」となり、パワーハラスメントの場になってしまうケースが少なくないことを指摘。



選択の自由 - raurublock on Hatena

卿は厄介な問題だという認識を欠いたまま首を突っ込んでしまったのかもしれないとコメント

『あの課題の設定された目的(どの価値観を重視するかという話)とはかなり離れたところで、ふと哲学的な疑問が沸きました。選択の余地があるのと無いのと人間はどっちが幸せなんだろうという話。』

セクシュアリティにからまない別の設問を提示した上で、正答の無い問題を考えること自体は良いことなのではないか、という視点を提示。




戦線が拡大しすぎてこれ以上追うのはむりぽ。

興味がある人は元エントリのはてブ>「このエントリを含むエントリ」で確認してください。現時点で32コある。

あとはキーワード無人島はてブ検索とか。エントリについてるタグで飛ぶとか。

派生エントリにはトラバ売ってるけど元エントリトラバ打ってないエントリも多い。

はてブコメントにも興味深いものが多いけど力尽きた。

(そしてこのエントリ戦線の一部となった。)



>id:Midas 面白そうなのでエントリ書いてここのブクマで告知してもらえればまとめに追記しますよ。

>id:matcho226 あまり考えてなかったので反省した。まとめエントリがほしかったけどなかったので書いてみた。

2008-12-07

就活 グループディスカッション メモ

GDは上手くいった流れをメモ

・国内・教育出版インターン 通過

時間40分でテーマについて議論。具体的なアクションプランを3つ提示。発表


1.自己紹介アイスブレイク

メンバーの雰囲気次第で通過率が異なるのは否めない。

メンバーが話したがりの人なのかそうでないのかを知るだけでも得るものがある。

(議論になるとだんまりタイプもいるが・・・)

名前をさっと言えるようにしておく。


2.課題の統一化

個人で課題を噛み砕く時間を設ける(1~2分)
目的を明確化

まず言葉定義をし、結論を出すにはどのような点を論じれば良いかをあげる

今回はターゲットを絞り込み、その特性を仮定。(消費者ニーズに対応させよう!)

状況・資源を理解

与えられた状況やコスト時間的制限を意識

目的達成のベストだと思う方法(リスクを減らす方法)を考える

役割分担・時間配分の提案

「司会を決めませんか?」の提案があったのだが、誰も立候補しなかったので私が司会に。(言いだしっぺがやれよ・・・)

しかし、「それぞれが課題達成のために意識して取り組もう」という意で、必要があればそれぞれ司会やタイムキーピング・書記を行うことを提案。

(決めなくても良いとは思っているけれど、どうなんだろう?)


3.議論

前半ブレインストーミング(7分間)

実現性などは考えず、多角的な論点をあげる事を目標にする。

反対意見揚げ足取りは控え、むしろ上がった意見を拾い捲る。

今回は一人30秒以内と時間を決めてなるべく多くの意見を出すようにした。

話の長い人対策;「時間がないので、要点をまとめると・・・?」

一枚の紙にまとめ情報を共有し、議論が後戻りしないようにしておく。

後半は挙がった論点の整理(抽象化・分類)(15分)

フレームワーク化する。

4C分析とかしっていると楽ちん。

挙がった論点をそのテーマにあわせて。

今回はターゲットに対して【コストパフォーマンス】【インセンティブ】【代替案】を行うことに。

それから論点の優先度を決め、それぞれ発表のために具体化する。


4.発表のための資料作り(3分)


こんな感じで、時間内にまとめることができた。


気をつけたこと

「どうグループ貢献できたか」

国内企業GDで一番見られるのは「協調性

しかしそれはなあなあにするのではなく、助け合い精神

貢献」するのは、リーダーシップだけではなく、ズレている論点を修正したり、足りない観点を補ってあげたり、後戻りしないようにすることも含まれる。

意見を「伝える」こと。

その気になれば一言でもいい。

端的に明確に、相手に自身の立ち位置を伝えることが大事。

意見を「理解」すること

必要があれば「それは〓ということですか?」「○○さんのおっしゃった〓と〓ていう点では同じなのでしょうか?」

相手が言っていることを、議論の場に結びつける役割もある。

時間内にチームで一つのアイディアをまとめることはビジネスマンには当然。シビアに行く。

自分にしかわからないメモだけれど、アドバイスがあったらください><

2008-10-21

http://anond.hatelabo.jp/20081021195631

自分は必死に非コミュを隠しているうちに顔色やテンションを読むスキルがついたから  

就活中は妥協を導ける人として棲み分けを図った  

GDとか脇の下ぐっしょりさせながらも平気な顔で司会して終わったらトイレ直行

2008-10-17

http://anond.hatelabo.jp/20081006220009

YourFileHostのCAPTCHA画像をなんとかするの続き。

その後、適当にいじったら、手元環境で1枚あたり25秒くらい→だいたい2.5秒くらいで判別できるようになった。このくらいなら使えるかな。

速度向上に一番効いたのは、Token#importで画像を比較しているところの修正。他は細かい手直し。

使い方は前のやつと変わってません。

あと、テストに100枚くらいCAPTCHA画像食わせてみたけど、とりあえず全部正しく判定できた。

動作確認用のスクリプト (run.rb)

カレントディレクトリ以下にある*.gifCAPTCHA画像ファイル適当に判別するスクリプト。動作確認用にどうぞ。

後述のdecaptcha.rbと同じディレクトリ適当に置いてchmod +xしてね。

#!/usr/local/bin/ruby
$LOAD_PATH << File::dirname(File::expand_path($0))
require 'decaptcha'

STDOUT.sync = true

Dir.glob('*.gif').sort.each do |file|
  correct = File::basename(file, '.*')
  puts "Processing file: #{file}"
  start_time = Time.now
  ret = DeCAPTCHA.decode(file)
  elapsed = Time.now - start_time

  puts "  Result: #{ret} (=> #{(correct == ret) ? "Ok" : "Fail"})"
  puts "  Elapsed time: #{elapsed}"
  puts
end

コード (decaptcha.rb)

#!/usr/local/bin/ruby
require 'rubygems'
require 'gd2'
require 'pp'

#
#= CAPTCHA画像解析モジュール
# CAPTCHA画像ファイルを食わすとあら不思議Stringが出てくるよ。
# YourFileHostのやつに対応。
#
#== Usage
# decoded_str = DeCAPTCHA.decode("some_captcha_image.gif")  #=> String
# 失敗したらnilが返る。
#
module DeCAPTCHA
  DEBUG = false

  #=== CAPTCHA画像デコード
  # file::    画像ファイル名のパス
  # method::  未指定でよい。男は細かい事を気にするな。
  # returns:: CAPTCHA画像解析結果(String) or nil (デコード失敗時)
  def self.decode(file, method = DeCAPTCHA::Site::YourFileHost)
    return method.new(file).decode
  end



  #= CAPTCHA画像デコードクラス
  # このクラスサブクラスはimport, tokenize, stream_parseメソッドの
  # 実装を含む必要がある。
  class Site
    def initialize(file = nil)
      @pix = nil
      self.import(file) unless file.nil?
    end
    def decode
      return stream_parse(tokenize())
    end
  end

  #= YourFileHostのCAPTCHA画像を解析するクラス
  class Site::YourFileHost < Site
    def import(file)
      @pix = PixelMatrix.new.import(file)
      return self
    end

    # importしたイメージ(PixelMatrix)から、文字と思わしきパターンを
    # 抽出して上下マージンを切り取ってArrayにして返す。
    # returns:: Array of PixelMatrix
    def tokenize
      ret = []
      state = :initial
      for x in 0...@pix.width
        case state
        when :initial
          if !@pix.vline_blank?(x) then
            state = :tokenize
            pixel = PixelMatrix.new(0, 0, true)
            ret << pixel
            redo
          end
        when :tokenize
          if @pix.vline_blank?(x) then
            state = :initial
            next
          end
          x0 = pixel.width
          for y in 0...@pix.height
            pixel[x0, y] = @pix[x, y]
          end
        else
          raise 'NOTREACHED'
        end
      end

      ret.map! {|token| Token.new.import(token.cutoff_vmargin!) }
    end


    # PixelMatrixのArrayを受け取り、数字を判別。
    # tokens:: Array of PixelMatrix
    # returns:: String (判別結果)
    def stream_parse(tokens)
      rs = tokens.map {|x| x.guess.to_s }.join('')
      if rs.length != 4 then
        rs = nil
        if DEBUG then
          puts '- guess failed. dumping guess result of each token:'
          tokens.each_index do |i|
            print "##{i}:#{tokens[i].guess} "
            pp tokens[i].candidate
          end
          puts
        end
      end
      return rs
    end

    class Token
      @@digits = nil
      attr_accessor :candidate

      def initialize
        if @@digits.nil? then
          # 文字画像サンプルを作っておく
          @@digits = DIGITS_ASSOC.map {|digit|
            PixelMatrix.new(0, 0, true).import_array(digit) }
        end

        @candidate = Hash.new
      end

      # PixelMatrixを受け取り、文字画像サンプルと比較して
      # 一致率を計算しておく。
      # pixel:: PixelMatrix
      # returns:: self
      def import(pixel)
        @@digits.each_index do |i|
          digit = @@digits[i]

          if (digit.width - pixel.width).abs   > 4 or
             (digit.height - pixel.height).abs > 4 then
            @candidate[i] = -1  # サイズが違いすぎな場合、一致させない
            next
          end

          correct_bits = 0
          enlarged_width  = [digit.width,  pixel.width ].max
          enlarged_height = [digit.height, pixel.height].max
          for y in 0...enlarged_height
            dy = (y.to_f / digit.height * enlarged_height).to_i
            py = (y.to_f / pixel.height * enlarged_height).to_i
            for x in 0...enlarged_width
              dx = (x.to_f / digit.width * enlarged_width).to_i
              px = (x.to_f / pixel.width * enlarged_width).to_i
              correct_bits += 1 if digit[dx, dy] == pixel[px, py]
            end
          end

          @candidate[i] = correct_bits * 100 /
                          (enlarged_width * enlarged_height)
        end

        return self
      end

      # importのときの比較結果をもとに文字を推測
      # returns:: Fixnum or nil(失敗時)
      def guess
        digit, ratio = @candidate.sort {|a, b| a.last <=> b.last}.last
        digit = nil if ratio < 0 or ratio < 65
        return digit
      end
    end
  end


  #= 画素マトリックスクラス
  # 画像ファイルを食わせると、各ピクセル(画素)を2値(black(1) or white(0))に
  # 変換して、内部で保持する。
  # 以後、Matrixクラスのような感じで個々の画素アクセスできる。
  class PixelMatrix
    BLACK = 1
    WHITE = 0

    attr_accessor :width
    attr_accessor :height

    # width::  幅
    # height:: 高さ
    # is_flexible:: 自動的に伸張するか
    def initialize(width = 0, height = 0, is_flexible = false)
      @matrix = Hash.new {|hash, key| hash[key] = Hash.new(WHITE)}
      @width, @height, @flexible = width, height, is_flexible
    end

    # file:: 画像ファイル名のパス
    # brightness_threshold:: 画素を黒とみなす閾値 (0 - 255, default: 0x40)
    # returns:: self (DeCAPTCHA::PixelMatrix)
    def import(file, brightness_threshold = 0x40)
      gd = GD2::Image.import(file)
      @width, @height = gd.width, gd.height

      self.each_with_axis do |x, y|
        color = gd[x, y]
        greyscale = (color.red + color.green + color.blue) / 3
        self[x, y] = (greyscale > brightness_threshold) ?
          WHITE :
          BLACK
      end
      return self
    end

    def import_array(array)
      array.each_with_index do |str, y|
        str.split('').each_with_index do |c, x|
          self[x, y] = c.to_i
        end
      end
      return self
    end

    # PixelMatrixを画像ファイルとしてexport
    # file:: 新たに作る画像ファイル名のパス
    def export(file)
      gd = GD2::Image::IndexedColor.new(@width, @height)
      gd.palette << GD2::Color::WHITE
      gd.palette << GD2::Color::BLACK
      self.each_with_axis do |x, y|
        gd[x, y] = {
          WHITE => GD2::Color::WHITE,
          BLACK => GD2::Color::BLACK,
        }[self[x, y]]
      end
      gd.export(file)
      return self
    end

    # 指定された位置の画素を返す。
    # returns:: PixelMatrix::BLACK(1) or WHITE(0)
    def [](x, y)
      if !@flexible and !in_range?(x, y) then
        raise RangeError
      end
      return WHITE if !@matrix.has_key?(y)  # XXX: for optimize
      return @matrix[y][x]
    end

    # 画素に値を設定。
    # returns:: PixelMatrix::BLACK(1) or WHITE(0)
    def []=(x, y, val)
      unless in_range?(x, y) then
        raise RangeError unless @flexible
        @width  = (x >= @width)  ? x + 1 : @width
        @height = (y >= @height) ? y + 1 : @height
      end

      @matrix[y][x] = val
    end

    def in_range?(x, y)
      ((0...@width) === x and (0...@height) === y)
    end

    # 指定された軸をもとに画素を走査し、Arrayに変換。
    # 例えば、to_a(:vertical, 10) とすると、x == 10 な列を取り出して
    # Arrayにして返す。
    #
    # axis:: 軸を指定 (:vertical または :horizontal)
    # pos:: 位置を指定。_axis_で指定した軸と直交する軸における位置を指定。
    def to_a(axis, pos)
      {:vertical => lambda {
        (0...@height).map {|y| self[pos, y]}
       },
       :horizontal => lambda {
        (0...@width).map  {|x| self[x, pos]}
       },
      }[axis].call
    end

    # returns:: Array
    def hline(y)
      self.to_a(:horizontal, y)
    end

    # returns:: Array
    def vline(x)
      self.to_a(:vertical, x)
    end

    # X軸方向に画素を走査。
    # y:: どの位置で走査するか
    # returns:: 指定された軸の上にドットが存在: false, 無い: true
    def hline_blank?(y)
      return true if @matrix.has_key?(y) == false # XXX: for optimize
      for x in 0...@width
        return false if self[x, y] == BLACK
      end
      return true
    end

    # Y軸方向に画素を走査。
    # x:: どの位置で走査するか
    # returns:: 指定された軸の上にドットが存在: false, 無い: true
    def vline_blank?(x)
      for y in 0...@height
        return false if self[x, y] == BLACK
      end
      return true
    end

    # 上下のマージン削除した新しいPixelMatrixを返す。
    # returns:: PixelMatrix
    def cutoff_vmargin
      pixel = PixelMatrix.new(0, 0, true)
      head = 0
      tail = self.height - 1

      head.upto(tail) do |y|
        if !self.hline_blank?(y) then
          head = y
          break
        end
      end
      tail.downto(head) do |y|
        if !self.hline_blank?(y) then
          tail = y
          break
        end
      end

      head.upto(tail) do |y|
        0.upto(self.width - 1) do |x|
          pixel[x, y - head] = self[x, y]
        end
      end

      return pixel
    end
    
    # 自身の上下のマージン削除する。cutoff_vmarginの破壊版。
    # 速度稼ぎのために直接@matrixを触ったり、すこしずるをしている。
    # 効率は、ほんの少しだけ速くなったような誤差の範囲のような感じ。
    # returns:: self (PixelMatrix)
    def cutoff_vmargin!
      head = 0
      tail = self.height - 1

      head.upto(tail) do |y|
        if !self.hline_blank?(y) then
          head = y
          break
        end
      end
      tail.downto(head) do |y|
        if !self.hline_blank?(y) then
          tail = y
          break
        end
        @matrix.delete(y) if @matrix.has_key?(y)  # XXX
      end

      if head > 0 then
        head.upto(tail) do |y|
          next if !@matrix.has_key?(y)            # XXX
          @matrix[y - head] = @matrix.delete(y)   # XXX
        end
      end
      self.height = tail - head + 1

      return self
    end
    
    def each_with_axis
      for x in 0...@width
        for y in 0...@height
          yield(x, y)
        end
      end
    end
  end
end

class DeCAPTCHA::Site::YourFileHost::Token
DIGITS_ASSOC = [
  # 0
  ["00000000011111110000000000",
   "00000001111111111110000000",
   "00000011111000001111000000",
   "00001111111100010011110000",
   "00011111100000110000111000",
   "00111111000000100001111000",
   "00111111110001000001111100",
   "01111111000010000011111110",
   "01111100000110000111111110",
   "01111111000100000111111110",
   "11111100001000001111111111",
   "11100000001000011111111111",
   "11111000010000011111111111",
   "11111000110000111111111111",
   "10000000100001111111111111",
   "01100001000001111111111110",
   "01100010000011111111111110",
   "01100010000111111111111110",
   "00111100000111111111111100",
   "00011100001111111111111000",
   "00001100011111111111111000",
   "00001111111111111111100000",
   "00000011111111111111000000",
   "00000000111111111100000000"],
  # 1
  ["00001",
   "00111",
   "11111",
   "11111",
   "10001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001",
   "00001"],
  # 2
  ["0000011111111110000000",
   "0001111111111111000000",
   "0011110000000010000000",
   "0110000000000100000000",
   "1100000000001100011110",
   "1000000000001000001111",
   "1000000000010000000111",
   "1000000000110001111111",
   "1000000000100001111111",
   "1000000001000000011111",
   "0100000011000001111111",
   "0011000010000111111110",
   "0011000110000001111110",
   "0000001100000111111100",
   "0000001000011111110000",
   "0000011000000111100000",
   "0000110000000000000000",
   "0000111111111111111111",
   "0001111111111111111110",
   "0011111111111111111100",
   "0011111111111111111100",
   "0111111111111111111000",
   "0111111111111111110000"],
  # 3
  ["000000011111111110000000",
   "000001111111111111100000",
   "000011100000011111111000",
   "000111000000111111111000",
   "000110000001111111111100",
   "000100000001111111111100",
   "000100000011111111111100",
   "000110000111111111111000",
   "000010000111111111111000",
   "000000001111111111100000",
   "000000011111111111000000",
   "000000011111111110000000",
   "000000000000001100000000",
   "000000000000011100011100",
   "000000000000111000111110",
   "000000000000110000001110",
   "000000000001110001111111",
   "110000000011100011111111",
   "111000000111000000111110",
   "011100000110001111111100",
   "001111001110000111111000",
   "000011111100000011100000",
   "000000011000111000000000"],
  # 4
  ["0000000000011",
   "0000000000011",
   "0000000000111",
   "0000000001111",
   "0000000001111",
   "0000000011111",
   "0000000111111",
   "0000000110111",
   "0000001100111",
   "0000011100111",
   "0000011000111",
   "0000110000111",
   "0001110000111",
   "0001100000111",
   "0011000000111",
   "0111000000111",
   "0111111111111",
   "1111111111111",
   "0000000000111",
   "0000000000111",
   "0000000000111",
   "0000000000111",
   "0000000000111"],
  # 5
  ["000000001111111111111110",
   "000000011111111111111100",
   "000000111111111111111100",
   "000000111111111111111000",
   "000001111111111111110000",
   "000011100000000000000000",
   "000011011111111110000000",
   "000111111111111111000000",
   "001111100000000111000000",
   "001110000000000110001100",
   "000000000000000100011110",
   "000000000000001100000110",
   "000000000000011000011111",
   "000000000000011001111111",
   "000000000000110000011111",
   "000000000001100000111111",
   "110000000001100111111110",
   "011000000011000001111110",
   "011100000110000011111100",
   "001111000110011111111000",
   "000111111100001111110000",
   "000001111100000011000000",
   "000000001000011000000000"],
  # 6
  ["000000000000000110000000",
   "000000010001111111111000",
   "000001110000011100111100",
   "000011100000011000001000",
   "000111000011111000000000",
   "001111000001110000000000",
   "001110000000111100000000",
   "011110001111111111100000",
   "011100000111000011110000",
   "011000000010000001111000",
   "011000011110000011111100",
   "010000111100000111111110",
   "100000001000000111111110",
   "100001111000001111111111",
   "000011110000011111111111",
   "000000100000011111111111",
   "000011100000111111111111",
   "001111000001111111111110",
   "000010000001111111111110",
   "001110000011111111111100",
   "000111000111111111111000",
   "000011111111111111110000",
   "000000111111111111000000",
   "000000000111111000000000"],
  # 7
  ["0011111111111110001111",
   "0011111111111100000011",
   "0111111111111000000110",
   "1111111111111000111100",
   "1111111111110000001100",
   "0000000000000000011000",
   "0000000000000011111000",
   "0000000011000000110000",
   "0000001110000011100000",
   "0000011110001111100000",
   "0000111100000011000000",
   "0001111000000110000000",
   "0001111000111110000000",
   "0011110000001100000000",
   "0011110000001000000000",
   "0011100011111000000000",
   "0011000001110000000000",
   "0001000000110000000000",
   "0000000111100000000000",
   "0000000111000000000000",
   "0000000011000000000000",
   "0000001110000000000000",
   "0000001100000000000000"],
  # 8
  ["0000000111111111110000000",
   "0000011111111111111100000",
   "0000001111100000011110000",
   "0000000001110000000111000",
   "0011000011111000000011100",
   "0011100001111100000011100",
   "0011110000001110000011100",
   "0001111000011111000111000",
   "0000111100000111101110000",
   "0000011110000001111100000",
   "0000001111000011111110000",
   "0000111111110000011111000",
   "0011110011111000001111100",
   "0111100001111100011111100",
   "0111000000111110000111110",
   "1111000000011111000000111",
   "1111000000001111100011111",
   "1111000000000011111000010",
   "0111100000000001111100000",
   "0011110000000000111110000",
   "0001111110000001111110000",
   "0000011111111111111000000",
   "0000000011111110000000000"],
  # 9
  ["000000111111111110000000",
   "000001111111111111100000",
   "000111111111111001111000",
   "001111111111110000010000",
   "011111111111110000010000",
   "011111111111100000100000",
   "011111111111000001100000",
   "111111111110000001000111",
   "111111111110000010000001",
   "111111111100000110000111",
   "011111111000000100011111",
   "011111111000001000001111",
   "001111110000011000011111",
   "001111100000010001111110",
   "000111110000100000011110",
   "000001111111100000111110",
   "000000011111000111111100",
   "000000000010000001111100",
   "000000000110000001111000",
   "000100001100011111110000",
   "000111001100001111100000",
   "000011111000001111000000",
   "000000010000110000000000"],
]
end
__END__

2008-10-06

YourFileHostのCAPTCHA画像をなんとかする

破ろうぜ!CAPTCHA画像♪(うっうーん)

そんなわけで、みんな大好きなYourFileHostだけども、最近みてみたら、なんかCAPTCHA認証がついているわけじゃないですか。

でもこれってさーCAPTCHAといっても見るからに危ういというか、見れば見るほど簡単に破れてしまいそうな気がして、どうにもむずがゆいアンニュイな気分になってしまうわけです。

そんで、このたび適当にいじってみたところ、それなりに推測できるコードが書けたので、ここに張ってみますね。

やってることは単純で、こんな感じ

  1. CAPTCHA画像ファイルをよみこむ
  2. ピクセルごとにグレイスケールにして、それで2値にする
  3. この時点でじゃまな背景が消えて、文字の形がわかってしまうわけです
  4. 縦軸に点がないところで切って、文字ごとにばらばらにする
  5. 文字画像のサンプルと比較して、一致率が高いものを採用

使い方は、こんな感じで

require 'decaptcha.rb'
captcha_string = DeCAPTCHA.decode(filename)
if !captcha_string.nil? then
  # 判別成功時の処理
else
  # 判別失敗時の処理。失敗することもあるのでよしなに。
end

あ、Ruby/GD2入れといてね。sudo gem install gd2とかで入ります。多分。

判別率はそこそこ良い感じになったんだけども、富豪プログラミングがたたってか、いかんせん遅いです。

手元だと1枚判別するのに20秒くらいかかることもある。

そんなわけで誰かチューニングしてくれるとうれしい。

追記

実行速度を上げた改良版はこっちにうpしました。以下のコードは参考程度に。

コード (decaptcha.rb)

#!/usr/local/bin/ruby
require 'rubygems'
require 'gd2'
require 'pp'

#
#= CAPTCHA画像解析モジュール
# CAPTCHA画像ファイルを食わすとあら不思議Stringが出てくるよ。
# YourFileHostのやつに対応。
#
#== Usage
# decoded_str = DeCAPTCHA.decode("some_captcha_image.gif")  #=> String
# 失敗したらnilが返る。
#
module DeCAPTCHA
  DEBUG = false

  #=== CAPTCHA画像デコード
  # file::    画像ファイル名のパス
  # method::  未指定でよい。男は細かい事を気にするな。
  # returns:: CAPTCHA画像解析結果(String) or nil (デコード失敗時)
  def self.decode(file, method = DeCAPTCHA::Site::YourFileHost)
    return method.new(file).decode
  end



  #= CAPTCHA画像デコードクラス
  # このクラスサブクラスはimport, tokenize, stream_parseメソッドの
  # 実装を含む必要がある。
  class Site
    def initialize(file = nil)
      @pix = nil
      self.import(file) unless file.nil?
    end
    def decode
      return stream_parse(tokenize())
    end
  end

  #= YourFileHostのCAPTCHA画像を解析するクラス
  class Site::YourFileHost < Site
    def import(file)
      @pix = PixelMatrix.new.import(file)
      return self
    end

    # importしたイメージ(PixelMatrix)から、文字と思わしきパターンを
    # 抽出して上下マージンを切り取ってArrayにして返す。
    # returns:: Array of PixelMatrix
    def tokenize
      getter, tokenizer = lambda {|queue|
        [ lambda { return queue },
          lambda {|x, pixel|
            if pixel.nil? then
              x, pixel = tokenizer.call(x, PixelMatrix.new(0, 0, true))
              queue << pixel
              return x
            end
  
            if !@pix.in_range?(x, 0) or @pix.vline_blank?(x) then
              return [x, pixel]
            end
            x0 = pixel.width
            @pix.vline(x).inject(0) do |y, color|
              pixel[x0, y] = color
              y + 1
            end
            return tokenizer.call(x + 1, pixel)
          }
        ]
      }.call([])

      x = 0
      while (x < @pix.width)
        x = @pix.vline_blank?(x) ?
          x + 1 :
          tokenizer.call(x, nil)
      end

      getter.call.map do |token|
        # Token.new.import(token.cutoff_vmargin.shrink)
        Token.new.import(token.cutoff_vmargin)
      end
    end

    # PixelMatrixのArrayを受け取り、数字を判別。
    # tokens:: Array of PixelMatrix
    # returns:: String (判別結果)
    def stream_parse(tokens)
      r = []
      tokens.inject(nil) do |prev, cur|
        r << cur.guess
      end

      rs = r.map {|x| x.to_s}.join('')
      if rs.length != 4 then
        if DEBUG then
          puts '- guess failed. dumping guess result of each token:'
          tokens.each_index do |i|
            print "##{i}: "
            pp tokens[i].candidate
          end
          puts
        end
        return nil
      end
      return rs
    end

    class Token
      @@digits = nil
      attr_accessor :candidate

      def initialize
        if @@digits.nil? then
          # 文字画像サンプルを作っておく
          @@digits = DIGITS_ASSOC.map {|assoc|
            PixelMatrix.new(0, 0, true).import_assoc(assoc) }
        end

        @candidate = Hash.new
      end

      # PixelMatrixを受け取り、文字画像サンプルと比較して
      # 一致率を計算しておく。
      # pixel:: PixelMatrix
      # returns:: self
      def import(pixel)
        gcd = lambda {|a, b|
          a, b = [b, a] if a < b
          return a if b == 0
          r = a % b
          return gcd.call(b, r)
        }
        lcm = lambda {|a, b| a * b / gcd.call(a, b) }
        mul_to_lcm = lambda {|a, b|
          g = gcd.call(a, b)
          [b / g, a / g]
        }

        0.upto(@@digits.size - 1) do |i|
          if (@@digits[i].width - pixel.width).abs   > 4 or
             (@@digits[i].height - pixel.height).abs > 4 then
            @candidate[i] = -1  # 比較対象とサイズが違いすぎ
            next
          end

          mul_ax, mul_bx = mul_to_lcm.call(@@digits[i].width,  pixel.width)
          mul_ay, mul_by = mul_to_lcm.call(@@digits[i].height, pixel.height)
          enlarged_width  = @@digits[i].width  * mul_ax
          enlarged_height = @@digits[i].height * mul_ay

          # 文字画像サンプルと比較対象画像のサイズをあわせる
          # 幅・高さをそれぞれ適当整数倍して、最小公倍数に合わせて比較
          # (めんどうだから)
          correct_bits = 0
          (0...enlarged_width).each do |x|
            (0...enlarged_height).each do |y|
              if @@digits[i][x/mul_ax, y/mul_ay] ==
                 pixel[x/mul_bx, y/mul_by] then
                correct_bits += 1
              end
            end
          end
          
          @candidate[i] = correct_bits * 100 /
                          (enlarged_width * enlarged_height)
        end

        return self
      end

      # importのときの比較結果をもとに文字を推測
      # returns:: Fixnum or nil(失敗時)
      def guess
        digit, ratio = @candidate.sort {|a, b| a.last <=> b.last}.last
        digit = nil if ratio < 0 or ratio < 80
        return digit
      end
    end
  end


  #= 画素マトリックスクラス
  # 画像ファイルを食わせると、各ピクセル(画素)を2値(black(1) or white(0))に
  # 変換して、内部で保持する。
  # 以後、Matrixクラスのような感じで個々の画素アクセスできる。
  class PixelMatrix
    BLACK = 1
    WHITE = 0

    attr_accessor :width
    attr_accessor :height

    # width::  幅
    # height:: 高さ
    # is_flexible:: 自動的に伸張するか
    def initialize(width = 0, height = 0, is_flexible = false)
      @matrix = Hash.new {|hash, key| hash[key] = Hash.new(WHITE)}
      @width, @height, @flexible = width, height, is_flexible
    end

    # file:: 画像ファイル名のパス
    # brightness_threshold:: 画素を黒とみなす閾値 (0 - 255, default: 0x40)
    # returns:: self (DeCAPTCHA::PixelMatrix)
    def import(file, brightness_threshold = 0x40)
      gd = GD2::Image.import(file)
      @width, @height = gd.width, gd.height

      self.each_with_axis do |x, y|
        color = gd[x, y]
        greyscale = (color.red + color.green + color.blue) / 3
        self[x, y] = (greyscale > brightness_threshold) ?
          WHITE :
          BLACK
      end
      return self
    end

    # reverse function of to_assoc
    def import_assoc(assoc)
      assoc.inject(0) do |y, columns|
        columns.inject(0) do |x, color|
          self[x, y] = color
          x + 1
        end
        y + 1
      end
      return self
    end

    # PixelMatrixを画像ファイルとしてexport
    # file:: 新たに作る画像ファイル名のパス
    def export(file)
      gd = GD2::Image::IndexedColor.new(@width, @height)
      gd.palette << GD2::Color::WHITE
      gd.palette << GD2::Color::BLACK
      self.each_with_axis do |x, y|
        gd[x, y] = {
          WHITE => GD2::Color::WHITE,
          BLACK => GD2::Color::BLACK,
        }[self[x, y]]
      end
      gd.export(file)
      return self
    end

    def to_assoc
      (0...@height).map do |y|
        (0...@width).map do |x|
          self[x, y]
        end
      end
    end

    # 指定された位置の画素を返す。
    # returns:: PixelMatrix::BLACK(1) or WHITE(0)
    def [](x, y)
      if !@flexible and !in_range?(x, y) then
        raise RangeError
      end
      return @matrix[y][x]
    end

    # 画素に値を設定。
    # returns:: PixelMatrix::BLACK(1) or WHITE(0)
    def []=(x, y, val)
      unless in_range?(x, y) then
        raise RangeError unless @flexible
        @width  = (x >= @width)  ? x + 1 : @width
        @height = (y >= @height) ? y + 1 : @height
      end

      @matrix[y][x] = val
    end

    def in_range?(x, y)
      ((0...@width) === x and (0...@height) === y)
    end

    # 指定された軸をもとに画素を走査し、Arrayに変換。
    # 例えば、to_a(:vertical, 10) とすると、x == 10 な列を取り出して
    # Arrayにして返す。
    #
    # axis:: 軸を指定 (:vertical または :horizontal)
    # pos:: 位置を指定。_axis_で指定した軸と直交する軸における位置を指定。
    def to_a(axis, pos)
      {:vertical => lambda {
        (0...@height).map {|y| self[pos, y]}
       },
       :horizontal => lambda {
        (0...@width).map  {|x| self[x, pos]}
       },
      }[axis].call
    end

    # returns:: Array
    def hline(y)
      self.to_a(:horizontal, y)
    end

    # returns:: Array
    def vline(x)
      self.to_a(:vertical, x)
    end

    # X軸方向に画素を走査。
    # y:: どの位置で走査するか
    # returns:: 指定された軸の上にドットが存在: false, 無い: true
    def hline_blank?(y)
      hline(y).find {|color| color == BLACK }.nil? ?
        true : false
    end

    # Y軸方向に画素を走査。
    # x:: どの位置で走査するか
    # returns:: 指定された軸の上にドットが存在: false, 無い: true
    def vline_blank?(x)
      vline(x).find {|color| color == BLACK }.nil? ?
        true : false
    end

    # 上下のマージン削除した新しいPixelMatrixを返す。
    # returns:: PixelMatrix
    def cutoff_vmargin
      pixel = PixelMatrix.new(0, 0, true)
      head = 0.upto(self.height - 1) do |y|
        break(y) if !self.hline_blank?(y)
      end
      tail = (self.height - 1).downto(0) do |y|
        break(y) if !self.hline_blank?(y)
      end

      head.upto(tail) do |y|
        y0 = pixel.height
        self.hline(y).inject(0) do |x, color|
          pixel[x, y0] = color
          x + 1
        end
      end

      return pixel
    end
    
    def each_with_axis
      (0...@width).each {|x|
        (0...@height).each {|y|
          yield(x, y)}}
    end
  end
end

class DeCAPTCHA::Site::YourFileHost::Token
DIGITS_ASSOC = [
# 0
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
],
# 1
[[0, 0, 0, 0, 1],
 [0, 0, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1],
 [1, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1],
 [0, 0, 0, 0, 1]],
# 2
[[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]],
# 3
[[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 4
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]],
# 5
[[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
 [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 6
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 7
[[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 8
[[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1],
 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0],
 [0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
# 9
[[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1],
 [0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1],
 [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
]
end


__END__
Dir.glob('*.gif').each do |file|
  puts "Processing file: #{file}"
  p DeCAPTCHA.decode(file)
end

__END__

2008-06-02

さくらのレンタルサーバ ライトユーザが書く実情(または宣伝もしくは疑問)

http://anond.hatelabo.jp/20080601175525

他の有料レンタルサーバを使ったことないので、あてにはできないけど。

総評

ライトプランの制限

重要なこと

プラン変更は出来ない。変更したい場合は別プランで新規登録後、データを移すことになる。

その他

実際の環境

公式にはこちら

以下私の環境。これは割り当てられたサーバにより多少の違いがあり得る。その他詳細はアカウント毎に確認できる。

CPU Intel(R) Pentium(R) M processor 2.00GHz
メモリ 2GB
OS FreeBSD 6.1-RELEASE-p23 i386
Apache Apache/1.3.39
Perl 5.8.8
Ruby 1.8.5
Python 2.4.5

主なperlライブラリ

2007-11-06

大企業と小企業どっちが強いか考えてみる?

http://anond.hatelabo.jp/20071106230619

労働力が少なくなったら競争力低下するとはいえないだろ。一人当たりGDPが高い国は小国ばかり。中国インドのような人口大国は一人当たりGDP少ないし。

国のGDPのでかさと個々人の生活水準(≒一人当たりGDP)が別ってことぐらいわかれよ。


国の生産力=労働人口*個々の生産

何が問題なんだろう?


タイトルへ戻る

2007-06-15

俺が Ruby を覚えた方法

http://anond.hatelabo.jp/20070615171101

俺は大学四年まで全くきちんとしたプログラミングをやったことが無くて(大学講義Javaの超簡単なのを教わったぐらい)で、卒論プログラミングをしなくちゃならなくて、そのとき初めて Ruby を触った。

RubyOOP ですげーんだぜ、とか一部で云われていた時代で、有名なアプリケーションtDiary ぐらいしかなかった。はじめはクラスとかも解らずに何が何だか。そのとき tDiaryプラグインクラス使ってないから簡単に書けるよ、というどこかのチュートリアルをみて見よう見まねで。GD という画像ライブラリを使ったら、サンプルをちょっと弄るだけで画像が作れて面白かったんだ。で、それを日記で公開してみた。今見返すとものすごくしょぼいソース

そのときたまたま Ruby ハカーの方がそのプラグインリファクタリングしてくれて、クラスを使って抽象化してくれて、初めて OOP をほんの少しだけ理解して、こうやってクラスって使うんだなぁというのを知った。本当に運が良かった。

その後就職して仕事php ハカーのすごい先輩にいろいろ教えてもらって php を使って基本的な OOP は理解した(PHPDIS る人が多いけど、プログラミング初心者には良い言語だと今でも思ってる)。これまた運が良かった。

その後またまた Ruby を使い始めたら今までよくわからなかった部分もするする頭に入ってきてホント面白ろくて没頭して。今では一通りのことは Ruby でできるようになった。

プログラミングが解るなら、Railsソース(トリッキーなことやりまくってるのでつらいかも。ActiveRecordActiveSupport はその中でも解りやすい)を読んで、解らなかったら rubygems で興味のありそうなライブラリコード読んで、あたりが OOPRuby 覚えるには手っ取り早いかも。

今なら Rubyレシピブック 268の技Rubyクックブック ―エキスパートのための応用レシピ集 あたり読んでおけば良いんじゃないなぁ。

あと今はてダRuby を含む日記を書くともれなく ruby-dev な人たちがキーワードからたどって読んでくれるので、解らないことをつぶやいたりすると結構答えてくれるみたい。のではてダ使って勉強日記とか書くのも良いと思うよ。

とあんまり参考にならないと思うけど書いてみた。なんか目的見つけられて、楽しく覚えていけたら勝ちなんじゃないかな。たぶん。

2007-05-30

http://anond.hatelabo.jp/20070530135156

大概理解した。管理の甘いサーバサーバサイドスクリプトでのっとり、それが出来なきゃindex.htmlおいてのっとり表示orフィッシング、最悪○○.txtや○○.jpghtmlおいてクライアントサイドスクリプト嫌がらせorトロイつーとこですか。

うん。そういう感じ。

置き土産のフィッシングサイトレンタルサーバーの規約に違反して公開停止の措置をうけました。

よぼぼん。


GDで1.0倍とか掛けるのはよさそうな手だね。

画像しかアップできなくなっちゃうのが困りものだけど。

他になにか手があるかな、

認証APIあたりをつかって匿名アップローダーにするとかしか思いつかないや。


googleあたりでフォルダ名あたりから辿ってアタックしているんだろうね。

そこらへんはBBSあたりへの手口と一緒かも。

アップローダー。結局どれもずるずるなんだよね。

どうしたもんか。


ハックしてくるひとのために勝手口に鍵を掛けてないドアを用意して、

入れるようにしておいて、中にはいったらお茶でも出してまっててやりたい。

http://anond.hatelabo.jp/20070530010836

大概理解した。管理の甘いサーバサーバサイドスクリプトでのっとり、それが出来なきゃindex.htmlおいてのっとり表示orフィッシング、最悪○○.txtや○○.jpghtmlおいてクライアントサイドスクリプト嫌がらせorトロイつーとこですか。

どうも、その「ずるずるのアップローダー」はターゲットらしい。いろいろやられてる所が散見されました。

やっぱりIEのおせっかい仕様ガンだなぁ。firefoxだとcontent-typeを無視しないから、画像として表示しようとして、表示できなくて終わりだけど、IEだと中身がHTMLだとHTMLとして解釈しちゃうんだよな。

根本対策は、いったん画像コンバートしてから保存するようにして、画像として処理できないデータは破棄するしかないのかな。GDとかImageMagicで1.0倍に変換とかしたらうまくいったりしないのかな?あとはアップロード時にはCAPTCHA使うとか。

でも、その「ずるずるあっぷろだ」をやめて、世界的にはマイナー、ただしユーザはそこそこいるアップローダにしたら、とりあえず大丈夫な気がする。

この攻撃、のっとったサーバボットネットか何かから、手当たり次第に特定環境機械的に攻めてるだけじゃないかな?だから、狙われないマイナーな奴使うのも一つの手だと思うよ。

何はともあれサイト復旧がんばってください。

2007-04-25

GD-ROMってどうなったんだっけ。

- 転職ならen
- 派遣ならen
 
1ページ中1ページ目を表示(合計:20件)