タグ別アーカイブ: cookie

クッキーによるトラッキングをリアルタイムで可視化するFirefoxアドオン

collusion

ネットサーフィンを楽しんだ後に、ブラウザの胃袋いっぱいに食べさせられたクッキーを見てみると、「こんなに!」 と思った事ありませんか? おそらくこれらのクッキーは、どこから来て、どこを訪れたのか、私たちの行動をトラッキングをしていたんだろうなぁ、と漠然とは思っても、現実感がイマイチわかないのはなぜでしょうか?

Collusion は、クッキーによるトラッキングをリアルタイムでグラフとして可視化してくれる Firefox 5 のアドオンです。これをインストールしてネットサーフィンをしてみて下さい。思わずゾッとするほど、グラフが成長しているのを見る事になるでしょう。
続きを読む

Perlのmap関数って、結構使える

前回 に引き続き、クッキー処理についてのネタを1つ。

HTMLやらPerlやらの勉強を始めて結構経ちますが、まだまだ初心者の域をちょっと超えたぐらいかなというBlogrammerにとって、使ったことの無い関数、パッケージ、オブジェクト指向プログラミングなど、勉強すべき項目は山ほどあり、そんななかの1つが map 関数でした。まずは元ネタの紹介から。

日本最強WEB講座 [Smart(スマートスマート)]配列の超絶テクニック大全集 で「ソートされていない配列からユニークな要素だけを取り出す」例が紹介されています。

@array = (1,3,3,2,4);
%tmp;
@sort = grep(!$tmp{$_}++, @array);
print @sort, "n";
> 1324

これがなぜmap関数に結びつくかというと、grep、mapは共に

grep 式, リスト
map 式, リスト

あるいは

grep {ブロック} リスト
map {ブロック} リスト

という使い方をするからです。即ち

リスト(配列)の要素1つ1つに対し、式あるいはブロックを評価・実行し、その結果をリストとして返す

という共通性を感じたからです。武道で言えば「型」みたいなものでしょうか。武道の型には基本の美しさを感じると思いますが、Perlにもこのような美しさを感じてしまうのは私だけでしょうか?

さてこれが分かってからは、foreachwhile で配列の要素1つ1つに何か処理をしている箇所をピックアップし、map 関数が適用できないか洗い上げました。ココでは掲示板CGIの YY-BOARD に実装されているクッキー処理を例を挙げておきます。まずは init.cgi 中に定義されたオリジナルのコードです。

#-------------------------------------------------
#  クッキー取得
#-------------------------------------------------
sub get_cookie {
	local($key, $val, *cook);

	# クッキー取得
	$cook = $ENV{'HTTP_COOKIE'};

	# 該当IDを取り出す
	foreach ( split(/;/, $cook) ) {
		($key, $val) = split(/=/);
		$key =~ s/s//g;
		$cook{$key} = $val;
	}

	# データをURLデコードして復元
	@cook=();
	foreach ( split(/<>/, $cook{'YY_BOARD'}) ) {
		s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;

		push(@cook,$_);
	}
	return @cook;
}

で、map を使ってこんな風に書き直して使っています。

#-------------------------------------------------
#  クッキー取得
#-------------------------------------------------
sub get_cookie {
	# クッキーを分解取得する
	my %cook = map { my ($key, $val) = split /=/; $key => $val; } (split /;s*/, $ENV{'HTTP_COOKIE'});

	# データをURLデコードして復元
	map { s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg; $_; } (split /<>/, $cook{'YY_BOARD'});
}

2つの foreach をそれぞれ1行に凝縮し、コードの肝心な部分はたった2行で済んでしまいます。
う~ん、こんなことに美しいを感じてしまうのは変でしょうか?

Javascriptで投稿フォームを難読化-クッキーの日本語処理

前回ヌルコムアーカイブス・デジタル制作室 さん作成のツール AlphamericHTML を使った JavaScript による投稿フォームの難読化について書きましたが、今回はその際のクッキー処理について書いておきます。もちろん JavaScript によるクッキー処理を解説しているサイトは沢山あるので、基本はそちらを参照いただくとして、ここでは日本語の扱いについて書き留めておきます。

YY-BOARD はサーバーがユーザーから送られて来たクッキーをデコードし、レスポンスの際、投稿フォームにその内容を埋め込んでページの HTML を返すのが仕様です。フォームの難読化のためには、サーバー側は予め暗号化されたフォームを送信するだけとし、ユーザーエージェント(つまりブラウザ)側で解凍するという仕様に変更する必要があります。YY-BOARD では日本語を Shift_JIS で扱っていますので、クッキーを送出する際の URL エンコードも Shift_JIS を元にしています。エンコードされた文字列を JavaScript でデコードする例として unescape 関数を使う例が多数紹介されていますが、unescape 関数は UTF-8 としてデコードするのが仕様のようで日本語が文字化けしてしまいます。Perl であればサーバー側で Encode.pm などを使ってUTF-8でエンコード処理をすれば良いのですが、ここでは前述の ヌルコムアーカイブス さん作成「Escape Codec Library: ecl.js」を紹介します。このライブラリにある UnescapeSJIS 関数を escape 関数の代わりに使えば問題は即解決です。世の中には何とすばらしいモノを作っている方々がいるのでしょう!正に ヌルコムアーカイブス さんのおかげでウチの掲示板に平和が訪れたのです!!

とまぁ、感動はおいておいて、大したコードではありませんが以下にウチで使っているクッキー処理を載せておきます。6行目でユーザーエージェントが保存しているクッキーの値をデコードしています。投稿フォームがデコードされた後の適当なところで SetForm() 関数を呼び出せば、クッキーに保存された値がフォームに書き戻されます。以下のコードは、フォームタグが <form name="form" ...> の様に、属性「name=”form”」 が指定されていることが前提です。

function GetCookie(name) {
	var c = document.cookie.split("; ");
	for (var i = 0; i &lt; c.length; i++) {
		var v = c[i].split("=");
		if (v[0] == name) {
			return v[1] ? UnescapeSJIS(v[1]) : v[1];
		}
	}
	return "";
}

function SetForm() {
	var i, f = document.form;
	var c = GetCookie("YY_BOARD").split("<>");
	f.name.value  = c[0] ? c[0] : '';
	f.email.value = c[1] ? c[1] : '';
	f.url.value   = c[2] ? c[2] : 'http://';
	f.pwd.value   = c[3] ? c[3] : '';

	f.icon.options[0].selected = true;
	for (i = 0; i < f.icon.options.length; i++) {
		if (c[4] == f.icon.options[i].value) {
			f.icon.options[i].selected = true;
		}
	}

	f.color[0].checked = true;
	for (i = 0; i < f.color.length; i++) {
		if (c[5] == f.color[i].value) {
			f.color[i].checked = true;
		}
	}
}

ちなみに ecl.js の速度改善をはかった記事が こちら で紹介されています。ウチのサイトでも使わせてもらっています。