携帯でセッションIDが長いのが嫌なので短くしてみた

セッションファイルをNFSに保存する仕組みで。
ちょっと古い気もするけど Walrus::Session::Lite を使わせていただく。

最新バージョンは0.3
http://digit.que.ne.jp/work/product/module/Walrus/Session/Lite/Lite_0.3.tar.gz
URLをごにょごにょすると0.4もダウンロードできるっぽい(未検証)
http://digit.que.ne.jp/work/product/module/Walrus/Session/Lite/Lite_0.4.tar.gz

初期だとMD5(128ビット)のHex(30文字)なんだけど、長くていやなので短くする方法を考える。

セッションIDの生成部分を見ると、

$self->{'data'}->{'_session_id'} = &md5_hex(time(). {}. rand(). $$);

時刻 + 指定された値のハッシュスカラー + 乱数 + ApacheのプロセスID
('1200451632 HASH(0x86d8888) 0.277099502413986 32430')
で生成しているらしい。ちなみに重なったとき困るので、ファイルがすでに存在していたら、for文で10回回すという処理が入っていた。

でもモバイルサイトの場合、セッションをURLで引き回さないといけないので、あまり長いと気持ち悪い。ということで無理やり短くしてみる。要するには重ならなければいいんだよね!

あまり深く考えないで、とりあえず使える文字列を増やすという意味でBase64(22文字)にエンコードして、Base64で使う文字列でURLで使うとまずいものを置き換える(/ ⇒ -, + ⇒ ! ドット.でもいいけどドットは違う役目をさせるので避けた なんかフォームからhiddenで送信したときにおかしいからドットにした。+ ⇒ .)。
ついでにデフォルトで使っているPurePerlモジュールを、Coreモジュールに変えて、文字列を強制的に8文字で切る。

use Digest::Perl::MD5 'md5_hex';
↓
use Digest::MD5 'md5_base64';
$self->{'data'}->{'_session_id'} = &md5_hex(time(). {}. rand(). $$);
↓
my $new_session_id = &md5_base64(time(). {}. rand(). $$);
<del>$new_session_id =~ tr/+/!/;</del>
$new_session_id =~ tr/+/./;
$new_session_id =~ tr/\//-/;
$new_session_id = substr($new_session_id, 0, 8);
$self->{'data'}->{'_session_id'} = $new_session_id;

セッションIDが正しい文字列かどうかチェックしている部分があるので、そこも修正。

sub is_valid_id {
〜略〜
$session_id =~ /^[0-9a-f]+$/$session_id =~ /^[0-9a-zA-Z\!\-\.]+$/

とりあえずこれで、セッションIDが8桁に!!!!!

http://yukiex.jp?s=7cdd3992f1d20da50325bf1d62802407

http://yukiex.jp?s=yQE8D-NK

ん〜こんなんでいいのかな?
めっちゃアクセスくるサイトではやっちゃいけないですかね><

とりあえず僕はセッションのデータにUser-Agentと端末固有ID(サブスクライバIDなど)を含めておいて、違ったら新しいセッションを作るようにセッションコントロール側で処理してる。

しかしこのソース、何分年代ものだからなのか use warnings すると warning 出すぎなんでチョコチョコ修正して終了。