BASIC認証を気楽に安全に使う

新システム200記事目ということで、まぁすばらしいですね。
旧システムが1133記事なので、合計1333記事ということですね。
1日1記事以上の割で書いてるから3年半以上だなとなるわけだが、
具体的には2005/05/31からだから、まぁ3年半ですね。
まぁ以前も書いたような覚えがあるが、古い記事はよくわからない記事も多い。
けど非常によい記録になってるのも多いのでかなり有意義な日記ではないかなと。


どうもCentOSでは標準でWebalizerってのが入ってるみたい。
これはApacheのアクセスログを解析するもの。
cronに登録されてて毎日解析プログラムが動いているだけです。
この手のものとしてはLogwatchというログファイルの抜粋メールをrootに送ってくれるやつとか。
さて、結果は/var/www/usageにあるので、Apacheから見れるようにしたいですね。
実はその設定が/etc/httpd/conf.d/webalizer.confだったのか…
いらんと思って.conf_にしてた。


さて、この設定ファイルでは127.0.0.1以外からのアクセスを禁じてた。
うーん…それでは不便と192.168.0.を追加しようと思ったのだが、
けど出先でも見たいし、家庭内に悪意がいないとも限らんし…
まぁ僕は別にアクセスログは個人情報とは思ってないんだけどね。
ただそういう考えをする人がいればなんか制限をかけた方がいいだろうと。
それで考えたのはHTTPS強制とBASIC認証の組み合わせ。
BASIC認証ならApacheの設定だけで簡単に認証かけれますからね。
BASIC認証は特に暗号化を行わない認証だけど、
HTTPSと組み合わせればパスワードの流出は多分防げる。
多分というのは、ブラウザが自動でパスワードを再送信する範囲がわからないから。
ただ、一般に成功したディレクトリ以下なので、
https://www.example.com/private/foo.phpで成功したら、
HTTPSの範囲でしか再送されないだろう、という予測が当たればまぁ安全。
あとBASIC認証は平文で送信されるので、サーバーに保管するのは暗号化したパスワードでOK。
そうなんですよね。そういう意味では暗号化しないというのは利点です。
IMAPとかもCRAM-MD5とかじゃなくてSSLで暗号化して平文認証を選んでると。


ただ具体的な設定は少しめんどくさい。
というのもSSLの場合だけBASIC認証をするためには、
VirtualHostディレクティブを使わないとだめなんだよね。
それで元のwebalizer.confのアクセス制限を行うLocationディレクティブを全削除して、
ssl.confをいじることにした。
なんでssl.confなのかというと、同じVirtualHostディレクティブが二個あると後に読み込んだのが無視されるから。
ssl.confではもともとSSLの設定にVirtualHostディレクティブを使ってるので…


(元々ある設定)

AuthType Basic
AuthName "Welcome Private Zone"
AuthUserFile /var/www/.htpasswd
Require valid-user



RewriteEngine On
RewriteBase /usage
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://libserver.ddo.jp/usage/$1 [L,R]

以前から使ってるHTTPS強制のrewriteと、Port 443からのアクセスの場合のみのBASIC認証だけですね。
わかってしまえば非常にシンプルですね。
まぁHTTPSがport 443以外にあるならまずいですが、じゃなければこれでOKだと。
.htpasswdはApacheから見えないところに置けば非常に安心です。
まぁ見えるところにおいても.htから始まるのは見えない設定だろうけど。
作成もコンソールからやるのがもっとも簡単です。

# htpasswd -c /var/www/.htpasswd user

-cを付けてやればファイル作成もやってくれる。当然2人目からは-cは付けない。
まぁこれでOKですね。


そういえばカウンタのログは制限かけてないなと思って、同様に書いてみた。
ログはscount/XXX.csvとscount/XXX.countにあるんだけどね。
SuExec以後は600にしてPHP以外からアクセスされないようにしてたけど、
これも非常に便利な資料なのでHTTPSで見れるようにした。



AuthType Basic
AuthName "Welcome Private Zone"
AuthUserFile /var/www/.htpasswd
Require valid-user



RewriteEngine On
RewriteBase /scount
RewriteCond %{HTTPS} off
RewriteRule ^(.*)\.(csv|count)(.*)$ https://libserver.ddo.jp/scount/$1.$2$3 [L,R]

2つの拡張子だからLocationMatchディレクティブを使ったけど、
csvだけなら*.csvでLocationディレクティブを使った方が読みやすいですね。
まぁrewriteもこんな感じでOKです。
これでログも安心して見られる土壌が出来ました。
ちなみにAuthNameが同じところは同じユーザー名・パスワードの組が送られることがある。
まぁしかし実際は同じドメインに限られそうです。


BASIC認証なんて…と思いますけど、
使い方を吟味すればまぁまぁ安全に使えます。
BASIC認証にはログアウトがないというのもそうなんですが、
結構ブラウザのお節介がどの程度かによって変わってくる話です。
だから多くの人が使うところでBASIC認証はよろしくないと思います。
かっこわるいですしね。めんどくさいけどPHPで作ればいいです。
OKならSessionにREMOTE_ADDRとHTTP_USER_AGENTをくっつけた文字列を書き込めばいいですね。
それを比較すればかなり安心して使えます。
Cookieは盗まれたら終わりだから、大切な事はSessionで管理するのがいいです。
そしてSession IDが盗まれても、Sessionに登録されてるIPとUAが一致すれば本人に違いないと。
まぁそういう仕組みを作ればいいんです。簡単ですね。
だけど後付で付けるにはそれは大がかりな仕組みだし、内輪でしか使わないわけだから、
そういうときはBASIC認証というのは結構便利な仕組みだと言うことです。

新Libserverを調整した一日のこと

とりあえず何があったのかというのは回復後すぐ記事書きましたが、
まぁその後いろいろやっていくうちに完成しました。
しかし、CentOSに移行しても何にも違和感ないな。
Libserver以外で使ってるLinuxディストリビューションはすでに全部CentOSだったからな。
まぁこれで全部CentOSに統一されたと。
CentOSは一応RedHatの本流と思っていいのかな?


さて、最初にyumにリポジトリを追加してみた。
RPMforgeEPELのRHEL 5用リポジトリを入れた。
いずれもrpmを落としてきてインストールして、yum updateするだけ。
CentOS 5はRHEL 5のバイナリが必ず使えるとも言えないらしいけど、
2つともCentOSにも対応していると言っているので安心です。
Serverでインストールすると標準でApache2・PHP 5・Dovecot・BINDは入ってる。
まずPHPのFastCGI動作のためにmod_fcgidを導入。
それで/etc/httpd/conf.d/fcgid.confなどをいじる。
「FastCGIは本当に速いけど…それだけ?」「みんなにFastCGI用PHPを配りにいきましょう」の記事を見ながらやった。
過去の記事を参考にしながらやってるのだが、2日以上の記事にまたがってると、
前の方の記事にはいらんことも書いてあるのよね。使うときは注意するといいですね。
あと、php.confとかperl.confなどのCGIの高速化環境などの設定ファイルがあるけど、
いらんので無効化のためにphp.conf_などにリネーム。.confで終わらなきゃいいんですよ。
これでApacheは完成ですね。ただし、ここで問題が発覚。
SELinuxがONになってる。getenforceコマンドで確認できるんですけどね。
SELinuxは非常に複雑なので現状はOFFにするのが実用的。
なので無効化を行うことに。

# setenforce 0

これでとりあえず無効化できるのでこれで動くかチェック。
これである程度問題は解決できた。あと設定ファイルのミスを直せばOKだった。
それでSELinuxを無効化するには設定ファイルを変えないといけない。
/etc/sysconfig/selinuxをSELINUX=disabledのようにすればOK。
あとPHPにmbstringが入ってなかったのでphp-mbstringをyumで導入
mbstringはPHPとセットで入れるものだと、日本人は思ってるはず。
あとBlognplusで必要なgdもyumでphp-gdとして導入。


次にPostfixの設定。
どうもRHELでは標準のMTAはsendmailのようです。
現代人はPostfixの方が好きなので、次のコマンドで標準MTAを変更。

# update-alternatives --config mta

さて、Postfixの設定だが、まぁ基本的にはあまり変えることもない。
/etc/postfix/main.cfを編集。
myhostnameとmydomainとmynetworksとhome_mailbox=Maildir/ぐらいですね。
最近はMaildir形式が一番COOLだと思われているようです。
このようにすると各ユーザーのホームディレクトリにMaildirディレクトリができて蓄積される。
テストはmailコマンドを使って行えばOK。

$ mail foo
Subject: Hello world
Hello Postfix world(最後にはCtrl+D)
Cc:

こんな感じでOKです。宛先を単にfooとすると、foo@libserver.ddo.jpのようなところに送られる。
まぁ自身のfooユーザーに届くということです。
標準MTAを変更してあるのでPostfixから送られてるはず。
ホームディレクトリのMaildirのnewに届いたメールのファイルがある。catとかで見るとわかる。
するとPostfixが受け取ったメールである旨がRecivedのところに書かれてる。
まぁ外部への送信、外部からの受信とテストする。
mynetworksの設定がきちんと出来てればオープンリレーの心配もたぶんない。
Mail relay testing (Abuse.net)で確かめると多分うまくいくはず。
これはmynetworksの範囲以外からはmydestinationで定義した自身宛以外のメールは受け取らんから。
あとDovecotの設定もたいしたことはない。
/etc/dovecot.confを編集。
imap imaps pop3 pop3sを有効にして、Maildir用mail_locationをコメントアウトするだけ。
セキュアなプロトコルは置いておいて、これでメールは使えるようになった。
セキュアなプロトコルについてはApacheにhttps、Postfixにsmtps、Dovecotにimaps・pop3sを導入した。
「SSLの鍵を打ち出す単純な方法」「SPAMメールでないかはっきりさせるSMTP-AUTH」をそれぞれ丸写し。
まぁ丸写し以外どうにもならんような複雑な作業だから困る。
HTTPS強制は「よく切れるナイフmod_rewriteは大切なURLを守る」の記事の通りやった。

RewriteRule ^admin\.php(.*)$ https://libserver.ddo.jp/fdiary/admin.php$1 [L,R]

上のようにすれば特定のスクリプトだけHTTPS強制も簡単ですね。
その後開放ポートの整理をして、
SMTP(25)・HTTP(80)・HTTPS(443)・SMTPS(465)・IMAPS(993)・POP3S(995)と互換性のため81だけにした。
外部から見たポートスキャンはShieldsUP! (GRC)を使うと便利。


さて、あとはSambaとBINDだが、どっちも別に外部からすればどうでもいい。
Sambaはyumで入れないとだめ。
今回はSambaの設定を非常に真面目にかいた。

[global]
interfaces = lo eth0
hosts allow = 127. 192.168.0.
map to guest = Bad User
[public]
guest only = Yes
create mask = 666
directory mask = 777

丁寧に書いた設定はこの程度です。
publicは気楽に使いたいということを実現したわけです。
map to guestをBad Userにすると、
存在しないユーザーでのログイン要求はGuestでのログインとみなすと。
そういうことでして気楽にGuestに入れます。
共有フォルダの設定でguest ok=yesではなくguest only=Yesとすると、
ユーザーがある人もない人もGuest扱いになる。
Guestはlinuxのnobodyに相当するのが普通なので、誰でもnobody。
fooユーザーから作ったファイルをtomユーザーからでも消せると。気楽でいいですね。
BINDはCentOSではchroot環境で動くのが標準になってるので、
まぁ別に変えることもないのでそのままいきます。
BINDにとっての/は/var/named/chrootにあるというのがchrootです。
なので/var/named/chroot/etc/named.confが設定ファイル、
/var/named/chroot/var/namedに諸々のゾーンファイルを置く。
ところがnamed.confがない。サンプルも見つからん。
しゃあないので別の環境で使ってたnamed.confを盗んできた。

acl localnet{  192.168.0.0/24; 127.0.0.0/8; };
options{
directory "/var/named";
forwarders { 192.168.0.50; };
version "unknown";
allow-transfer { none; };
allow-query { localnet; };
};
zone "localhost" IN {
type master;
file "local.zone";
};
zone "0.0.127.in-addr.arpa" IN {
type master;
file "local.rev";
};
zone "libserver.ddo.jp" IN {
ty pe master;
allow-update { none; };
file "lib_int.zone";
};
zone "0.168.192.in-addr.arpa" IN {
type master;
allow-update { none; };
file "lib_int.rev";
};

家庭用のBINDの設定はほとんどこれでOKです。
そりゃ192.168.0.XXXじゃなくて、192.168.1.XXXだったら変えないとダメだけど。
ここで定義されてない分はforwardersで指定したところに聞きに行ってくれます。
allow-updateはDHCPと組み合わせて使うときに役立つかも。
あとゾーンファイルは適当に書き方を見ながら書けばOK。


以上で大体完了。
そうそう、ddo.jpの更新スクリプトを/etc/cron.dailyに追加したんだった。

#!/bin/sh
wget -O - 'http://free.ddo.jp/dnsupdate.php?dn=name&pw=passwd' >/dev/null 2>&1

結果を全て/dev/nullに捨ててメールが届かないようにしてる。
あと/etc/cron.tabのcron.dailyとかの実行時刻はずらしておこうね。
標準ではcron.dailyは4時02分に実行になってた。
その設定になってる人は結構いるはず。みんながそうだとよろしくない。
夜間の適当な時間に変更しておけばいいですね。
ddo.jpは便利でいいですよと。まぁ無料ユーザーはTOPページに検索窓置くことになってるけど。
実はlibserverのTOPページにあるんですよ。まぁちょっと本文が長いので見えにくいですが…
最後にマシンがすごく高速になったので日記トップページの生成時間を。
まぁBlognplusが出してる数字だから参考になるようなならないようなだけど。
平均0.472秒でした。当然FastCGI動作で。
旧LibserverではApache組み込み動作で2.26秒、FastCGI動作で1.98秒でした。
確実に生成速度は高速になってますね。
今まではちょっと時間がかかる感じでしたが、今は一瞬ですね。

急に壊れたから急に新しくした

えらいことでした。再起動したら急に起動できんもんで。
なんかRSS取得失敗しとるとかで気付いた人もいるかも。
それでアクセスしてみたら、なんか「現在修理中」とか出てるし。
と心配してくれたなら、ごめんなさい。
一晩と少しかけて、新しいシステムに移行しました。
まぁ実はいらなくなった、Libserverよりもずっと強力なマシンがあったので、
これにCentOSを入れて、そこに必要なファイルを送ったわけですけどね。
だから前のLibserverとは似てもにつかない代物になってます。
まぁCentOSへの移行も、新マシンへの変更も後々やるつもりだったので、
それを前倒しにしたということです。


ただ痛かったのはファイルシステムがぐちゃぐちゃになってたこと。
lost+found送りになってたファイルが山ほど。
実はfdiaryのログファイルも飛んでました。
どうやって回復したかというと、
実は11月15日にhtdocs以下はバックアップを取ってました。
定期的に取ってるんですよ。
これで11月15日の状態に戻して、fdiaryはThunderbirdのRSSから回復。
カウンタは幸い残ってたので、これは電源が消える前の状態に復帰できました。
いろいろ確認してHTTPは問題ないとなったので、HTTPに限り今回復させました。


これからPostfix・Dovecot・BINDと…専ら僕が使ってるサービスを回復させないとね。
まぁメールについては転送メールの行き先を変えてるので、
まぁ一応大丈夫かなと思ってるので、ゆっくり進めて行きたいなと。


回復中に気付いたのだが、PHPのFastCGI動作では、
$_SERVER[‘PATH_INFO’]が使えないらしい。
なんか正しいPATH_INFOがなんちゃらかんちゃら書いてあるが…
結論から言えば、php.iniに

cgi.fix_pathinfo=1

と追加して、$_SERVER[‘PATH_INFO’]の代わりに$_SERVER[‘ORIG_PATH_INFO’]を使う。
それにしてもPHPはApache組み込み動作を中心に考えすぎだよなぁ…
多少振る舞いが違うから違う変数名にしました、というのはひどい。
PATH_INFOってCGI発祥なんですよね。
そしてCGIにおける正しいPATH_INFOはPHPではORIG_PATH_INFOであるとなってるのよね。
なんか変な気がする。まぁとりあえずこれで動きますよと。
さてさて、Postfixを回復させますか。

いろいろやり方があるならこんなCもいい

Libserverが飛んでしまったので、書き直し。
プログラミングの授業ではCを使ってるのだが、
それでテストには使う気が起きないようなお茶目なプログラムを書いた。

#include 
#include
int die(char*);
main(int argc,char** argv){
FILE* fp;
int d=1,wd,ld;
if(argc<=2) die("usage: homework1 []");
( ld=atoi(argv[2]) )||die("Error : Invalid last date");
if(argc>3) d=1-atoi(argv[3]);
if(d<-5||d>1) die("Error : Invalid first day of week");
( fp=fopen(argv[1],"w") )||die("Error : Cannot open file");
fputs("Su Mo Tu We Th Fr Sa\n",fp);
while(1){
for(wd=0;wd<7;wd++){
fprintf(fp, d>0 ? "%2d " : " " ,d);
if(++d>ld) break;
}
fputc('\n',fp);
if(d>ld) break;
}
fclose(fp);
return 0;
}
int die(char* msg){
fputs(msg,stderr);
fputc('\n',stderr);
exit(EXIT_FAILURE);
return 0;
}

ファイル名・一月の日数、一日の曜日を指定したらカレンダーを出力してくれるプログラム。
homework1.cとしたけど、別に宿題ではない。
授業でファイル名・一月の日数、一日の曜日をプログラム内部で指定する、
というのはやったけど、まぁそれともだいぶ違う書き方。


一見したらなんじゃこりゃという内容かも。
Perlのdieに似たdie関数を定義した。
( ld=atoi(argv[2]) )||die(“Error : Invalid last date”);というのは、
Perlのor dieに似ている。まぁちょっと書き方違うけど。
普通Cではこんな書き方しないけど、実はこういう書き方もできる。
ただ、Borland C++ Compilerにはおそらく不正な代入と警告されますが…
あとatoiは文字列を数値に変換するもの。
読める数字がないときは0を返す。
||dieは返り値が0のときだけ死ぬということだからいいですね。
けど0のときも0を返す。
今回は0という数値自体不正だからこれでOK。
まぁそれはそうと、sscanfよりも便利かも知れませんね。
ちなみにatoiとかのシリーズはstdlib.hに入ってる。
そうそう、NULLポインタは絶対に0らしい。
Cの仕様でそうなってるんだとか。
日付を表示するところで三項演算子を使ってみた。
わかりにくいけど、結構スマートでいいですね。


まぁこんなプログラムは結構不気味ですけど、
それはそうとして授業ではprintf・fprintfばっかりですね。
実際はいろいろありますよね。
文字列を書き出すならfputs、
文字を書き出すなら標準出力にはputchar、ファイルへはfputcですね。
標準出力に文字列を書き出すputsは改行が入るので少し違うなぁと。
まぁprintfが一番便利ですけど、%とかで思わぬ問題が起きるかも知れんからね。
単に文字列を書くならfputsを使いましょうと。
標準出力に出したければfputs(str,stdout);とすればいいですね。
それはそうなんだが、ファイル関係の関数はfprintfとfscanfだけ引数が特殊なのよね。
fprintf(fp,”Hello!”); fscanf(fp,”%s”,str);
fputs(“Hello”,fp); fgets(str,sizeof(str),fp);
ほらファイルポインタが最初にあるか最後にあるか。
これは僕も困った。まぁ無用な混乱を避けるには便利なfprintfばっかり使うのがいいのかな?
と思わないこともない。

何がおかしいか知らんがHDDがおかしい言う

レポート書きつつ、ちょっと日記書きに行くかとおもってLibserverにアクセス。
ところがなんか重い。気になってSSHでログインするにも重すぎる。
それで画面をLibserverに切り替えるとエラーだらけ。
二進も三進もいかんので、一回強制的に終了させた。
それで再起動したが特に変わらない。けどかなり好転した。
まぁログインできる程度にはね。


/var/log/messagesを見るとえらいことだった。

kernel: hda: dma_intr: status=0x51 { DriveReady SeekComplete Error }
kernel: hda: dma_intr: error=0x40 { UncorrectableError }, LBAsect=7757346, sector=7757341
kernel: ide: failed opcode was: unknown
kernel: end_request: I/O error, dev hda, sector 7757341

どうもDMAでHDDにアクセスするときエラーが発生してるようだ。
原因はいろいろ考えられるらしく、
一見してHDDの故障のエラーに見えるからHDDを交換してみたが、直らないとか言う話もある。
別にこのエラーが出てるからと言って直接問題になることはないとか。
まぁしかし今のところ一番疑うべきはファイルシステムでしょう。


fsck -fという非常に危険なコマンドを実行してみた。
まぁディスクチェックを行うのだけど、まぁ強制的にやるので、
マウントしているディスクにやるとファイルシステムを破損させるかもとか。
するとエラーが出てきた。
修復後指示通りrebootをかけた。


しかし回復しませんね。エラーは出っぱなし。
まぁ原因を発見したいものですが、なかなかわからない。
うーん…HDD自体が壊れてるのかな。
そういう予兆であるという話もあるけど、そんなにはっきりとした根拠はないわけで…
まぁいろいろ考えてみます。

古い貯金システムは未だ孤立

今日、郵便局の前を通ったら、通帳に店名・口座番号を書いてもらいましょうと、
そんなポスターが貼ってあった。
これ以前にゆうちょ銀行が全国銀行データ通信システムに参加するに当たって、
従来の記号番号の他に店名・口座番号を設定すると。参考記事「銀行も日々変わるものですね」
これ自体は対応公式を見れば簡単に出せます。
まぁしかしいちいち変換公式で調べるのはめんどくさいから通帳に印字できるよと。
その取り扱いは9月の末には始まってる。
ぜひ印字しましょうという宣伝です。


実は以前、貯金に郵便局に非常に変な金額を入れに行ったとき、
チラシ見せて、これやってる?と聞けば、やってますよと言うから、
CTMをカタカタ操作して印字してもらった。
別になんてことはないですね。公式通りの結果ですから。
まぁ別に印字することにあまり意味はないような気はするけど、
窓口開いてる時間に郵便局かゆうちょ銀行の支店・出張所にいくなら、
ちょっとやってもらうといいことあるかもしれません。


同様のことで、通帳の切替も言ってましたね。
新規の担保定期貯金・担保定額貯金を入れるには、国営時代の通帳ではダメなんですよ。
担保定期・担保定額は総合口座通帳の後ろのページにあるやつ。
紛らわしいことに単独の通帳でやる、定期貯金・定額貯金ってやつもあるんですよ。
以前これのキャンペーン金利とかやってましたね。
多分この切替には印鑑いる。
けど一旦作ってしまえば預けるのはATMでできるわな。
同様に定期貯金・定額貯金を作ると定額定期貯金証書というものがもらえるらしい。
証書とか言うけど通帳で、ATMでも使えるとか。
非常に定期定額好きの人はこれの方が通帳埋まりにくいからいいかも。
僕は残念ながら現在ゆうちょ銀行の残高0円なので…


未だに郵便貯金と言いたくなりますが、
まぁ今はなんと言えばいいのかな…
けどいくら銀行法を根拠とする普通銀行とはいえ、他とはかなり違いますよね。
記号番号にしてもそうだし、預金の商品名が普通貯金とか定額貯金とかいうのもだし。
まぁ別にそれがどうしたという話ではあるのだけどね。
今日そのポスター見てゆうちょ銀行のホームページ行けば、
店名・口座番号から記号番号への逆変換ツールがあった。
一体何にいるのかというと、口座振替の申込書の訂正。
ゆうちょ銀行の貯金から自動的にお金を落とすのは自動払込みが使われる。
これは全国銀行データ通信システム参加後も変わらない。
だから他の銀行などで使用される口座振替の申込書に書いてはダメ。
それを訂正するために使うツールだと。
なんというか…難しいもんですね。

現金より便利な支払い方法?

日本の貨幣というと
1円、5円、10円、50円、100円、500円硬貨と、1000円、2000円、5000円、10000円紙幣と。
どれも非常に身近ですね。
銀行のATMから10000円紙幣を出すことは多そうですね。
500円硬貨はさすがにコインであることに違和感を覚える高価さですが、
まぁ1000円で硬貨と紙幣が切り替わるのはわかりやすいわな。
なんやかんや言うけどなかなか便利だと言うことです。
ところがだ、この10000円程度の紙幣がよく流通してるのはかなり珍しいことだそうだ。


USドルには1ドル、2ドル、5ドル、10ドル、20ドル、50ドル、100ドル紙幣があるそうだ。
ただし2ドルはあまり流通していないらしい。
さらに聞くところによれば、普段流通してるのは20ドル以下らしい。
それ以上だと偽造怖いとかおつりを出せないとかいうので困るそうだ。
20ドル言うと、2000円程度ですね。
あと硬貨も普通は25セントが最大ですからね。1ドルからは紙幣ですよ。
紙だらけでいろんな意味でかさばりそうですね。
あと、韓国のウォンは10000ウォンが最高額面で、これは現在640円程度。
まぁ今の日本円で見るとあまりにおかしいが、まぁ1000円札ぐらいの気分です。
これは本当にかさばりそうですね。


さて、例えばだ、5万円のテレビを買おうと思った。
まぁその程度なら現金で払うことが多そうですね。
カード払いだと便利ですけどね。まぁ限度額の加減もあるだろうが…
デビットカードだと口座残高が限度額だから意外と便利かも知れません。
まぁ実はこれは小切手の代わりそのものなんだけどね。
さて、ATMでもこの程度は下ろせますね。と一万円札を5枚もらってきて払うと。
便利ですねー。と言いたくもなりますね。
まぁUSドルで同じことすると感覚的には20ドル札25枚もらってくる程度だと。
うーん…同じ紙幣10枚超えると気持ち悪いものがあるよね。
以前銀行で1万円下ろすとき両替ボタンを押したら千円札10枚出てきたけど、気持ち悪かったな。
本当は千円札5枚と五千円札1枚で欲しかったのだけど。


そこで小切手なんてもんを使うらしい。
僕は、紙幣の偽造よりも、不渡りの方が怖いと思うけどね。
小切手というのは、当座預金作って小切手帳もらって、なんぼ払いますよと書いて相手に渡せば、
それを相手が銀行に預ければお金が来ると。
そういう仕掛けなのですが、怖いのは残高不足だとお金が来ないんですよね。
これ不渡り言うんですけど、結構ありそうで怖いですね。
不渡り防止のために、自己宛小切手というのがあって、銀行にあらかじめ金を渡して、
それで銀行がなんぼ払いますよとする仕組みがあって、
実は韓国ではこの仕組みで作られた10万ウォン小切手が広く使われているそうだ。
日本では流行ってないですけどね。
10万円までなら現金で払うと楽だし、あまりに高額なら振り込みで払うでしょ。
しかしアメリカとかでは普通に小切手で払うらしい。
すごい手間だと思うのだが…


まぁ実はこの小切手の代わりにデビットカードがあるんですよね。
これは便利ですよ。
最近日本でも多少VISAデビットを使う人が出てきたけど、
「VISAで」と言って、CATに通してもらってサインするか暗証番号入れるだけで完了。
払う方はそれだけで勝手にお金が落ちてると、
受ける方もきちんと契約すれば、手数料安いしそれなりにすぐ入金されるし。
クレジットカードよりも有利だそうです。
まぁ実際はそんなに真面目なところもないので、クレジットカードと一緒ですが。
以前からJ-Debitはあるが…まぁあんまり便利じゃないですね。
まぁ現金でも十分便利だけど、お金下ろさなくてよくて素早く済むならVISAいいですねということです。

正統派Pythonにお近づきになろうと

CPythonを入れてみた。
わざわざCPythonというのはIronPythonから入ったからですね。
CPythonというのはCで作られたPythonの意味だからね。
普通に配布されてるPythonはこれですね。
もしこれがDで作られてたらDPythonと呼ばれたかも知れん。


ダウンロードして、インストールして、PATH通してみた。
そしてpythonとコマンドプロンプトに打ち込む。
一瞬で立ち上がった。
そりゃそうだ。IronPythonが遅すぎるだけだ。
以前IronPython 2.0を入れたのだが、まぁ相変わらずだ。
そうそう、IronPython 2.0ではDLRという.NET Framework上の新環境の上で動いてるそうだ。
だが遅い。高速化なんて狙ってないに違いない。


それはそうと、Pythonですよ。Pythonらしいプログラム書きたいですね。

fh=open('test.txt','r')
for line in fh:
print '> %s'%line.rstrip()
fh.close()

まぁきちんとPythonの機能でやってます。
まぁこうやってPythonのソースコード見ると、行数少なくて済むよね。
インデントで書くというのは、終わり括弧とかいらんということだしね。
今まで、IronPythonで.NETのライブラリ使って書いたことあったよな。
まぁあれはせっかく.NETのライブラリ使えるしー、とか言ってやってたわけだが…

import clr
import System
mysr=System.IO.StreamReader('test.txt')
try:
while not mysr.EndOfStream:
System.Console.WriteLine("> "+mysr.ReadLine().TrimEnd())
finally:
mysr.Close()

こうやって書くと、なんというかむちゃくちゃリッチに見えますね。
だってC#での記述法をそのままPythonに持ち込んでるんだから。
try~finallyとかまさにそうですよね。C#のusing構文そのまま。
まぁしかしここまで厳密にやることはなくて、上のように非常に気軽に書けばOK。
と思うのだが、どうも.NETで書くと、ここはusingだなと思ってこうなるわけだ。
まぁCPythonで正統派のPythonの勉強もしていこうと言うことです。
かのyum、RedHat系でよく採用されているパッケージ管理ソフト、はPythonで書かれてるしね。


pythonはそれ自体が対話的な環境でかなり便利。
Windows版にはあったのだが、IDLEという非常に高級な対話的環境もある。
インデントとかの面倒も多少見てくれるのでいいですね。
対話的環境というと有名なのはRubyのirbですね。
あと、Perlでは自作したperlshなる対話的環境を個人的には使ってる。
なぜかWindowsにも入れているPHPではphshという対話的環境がある。
Windowsではライブラリの加減でうまく入らん。だから改造したphshもどきと言うべきだろうか。
と、実に
python(CPython 2.5)、ipy(IronPython 2.0)、irb(Ruby 1.8)、
perlsh(Perl 5.10)、pugs(Perl 6?)、phsh(PHP 5)
となぜかこんなにも対話的環境が入ってます。
あと、Firefoxのアドオン、Firebugのコンソールもlibserverのトップページでだけ有効にして、
JavaScriptの調査に同様に使ってる。
いろいろ調べるのに便利ですよ。

C#で動的型なんて流行らないと思うけど

なんかC# 4.0なんて考えてるらしい。動的型って…
IronPythonで開発してて思ったが、.NET Frameworkのライブラリは複雑すぎる。
System.Drawing.SizeとSystem.Drawing.Pointを使い分ける意味がわからない。
別に大きさ2のタプルでもいいじゃないか? と思わんこともない。
そういう都合を考えると、コンパイル時確認していただける仕組みは便利なんですよ。
そしてVisual Studioもそのように設計されている。
C# 3.0で型推論のvarが導入されたけど、あれは匿名型を使うときに必要だからですね。

var foo=new {first="Taro",last="Yamada"};

この無名の型の名を知らないから、varというキーワードを使うと。
それ以外にも使い道はあれど、あまり意味はないでしょう。
もっとも動的型導入の理由というのはJavaScriptとの連携とかいうのもあるそうだが。


.NET Frameworkのリフレクションの力でどの程度できるか試してみた。
といっても当然のことを書いてるだけですが…

  public static class DynamicWorld {
static public object call(this object self, string name, params object[] args) {
return self.GetType().GetMethod(name, Type.GetTypeArray(args)).Invoke(self, args);
}
static public object prop(this object self,string name) {
return self.GetType().GetProperty(name).GetValue(self, null); ;
}
static public void prop(this object self, string name, object value) {
self.GetType().GetProperty(name).SetValue(self, value, null);
}
static public object newobj(this string type, params object[] args) {
return Type.GetType(type).GetConstructor(Type.GetTypeArray(args)).Invoke(args);
}
static public object callstat(this string type, string name, params object[] args) {
return Type.GetType(type).GetMethod(name, Type.GetTypeArray(args)).Invoke(null, args);
}
}

未だC# 3.0をまともに使ってるわけではないが、これはC# 3.0が前提。
これ拡張メソッドなのよね。

sb.prop("Length", 0);
DynamicWorld.prop(sb,"Length",0);

下のように表記すべきを上のように簡略化できると。
とりあえずインスタンスのメソッドとプロパティにだけ対応させてみた。
本当はインデクサとかにも対応できるのだがかなりめんどくさいので。
IronPythonも結局こういうものの固まりだと思う。


さて、試しに全部これでプログラム書いてみた。

object sr="System.IO.StreamReader".newobj(@"C:\test.txt");
object sb="System.Text.StringBuilder".newobj();
sb.prop("Length", 0);
while (!(bool)sr.prop("EndOfStream")) {
sb.call("AppendLine", sr.call("ReadLine").call("Trim").call("PadRight", 20, '_'));
}
sr.call("Dispose");
"System.Console".callstat("Write",sb);
"System.Console".callstat("ReadKey", false);

拡張メソッドと可変長引数のおかげでそれなりに違和感なく使えます。
ただ、条件はbool型だろとかいうので、型変換が必要だったりというのはある。
しかしこれだけで動的に呼び出しているのです。
試しに、どっか大文字と小文字を入れ替えてみる。
コンパイルは通るものの、動かすとどっかで例外が出る。
これが動的に呼び出している証拠です。


作ってみて言うのもあれだが、あんまり使い道は思いつきませんけどね。
ただ割と簡潔に書けていますね。
.NET Frameworkのリフレクションの強さの証明と言えないこともない。
本当になんでもありの環境ですね。
それにしてもC# 4.0か…けど.NET Frameworkは2.0系のままなんだろうな。
だから動的型使ったソースコードも上に書いたようにされるのかな?
まぁそんな風に思わんこともない。

電池が長持ちするとうれしいですね

D-Snapですが、最近は非常に調子よく動いています。
2GBのSDカードを2枚使うということをしてるのですが、結構うまくいきます。
まぁ片方に偏って聴いてる気はしますけど…


3週間ぶりに充電しました。
まだいけそうなんだけど、電池表示が1本になったので。
せっかくなら音楽の転送もとおもったので、週末まで待ってやったわけですが。
ところでD-Snapは電池が80時間持つ(ノイズキャンセリングOFF)となってますが、
実際はそんなに長いこと充電しないで使うのは現実的じゃないかな?
SDカード変えるだけでかなり持ちが変わってくるわけで。
以前SDHCを使ってたときは異様に持ちが悪かった。あれはなんだ。
エコ充電モードという、電池にやさしい充電モードがあってこれを有効にしている。
すると9割程度の充電しかしないそうだ。
さて、3週間で大体33時間ぐらい使ったと思う。
それで9割で割ると37時間程度と、書いてあるよりかなり短いですね。
まぁ電池表示1本の状態でもあと一週間は使えるはずですけどね。
というあたりで実際80時間と書かれていても、そんなに持つかはよくわからないということ。
まぁしかし、概ね一ヶ月は無充電でも使える場合が多そうです。
どんなに少なく見積もっても40時間は持ちますから。


というわけで、D-Snapの充電は新しい曲の転送時にやれば十分。
これはかなり使い勝手がいい。
充電忘れてて使えんということを、携帯電話ではしょっちゅう起こしてますからね。
以前のVodafone 703SHfの使い方も豪快でしたね。
2週間使って、その週末の日曜の夜に電池切れてるなぁと思って充電…
夜中も電源付けっぱなしでこれ。結構便利でしたよ。
友人に言うと、電池持ちすぎだと言われますけどね。
SoftBank X01Tは見た目通り電池の持ち悪いですね。3日しか持ちませんよ。
まぁ使う頻度も増えたけど。主にスケジュール管理のために。
普段は夜に残量チェックするから大した問題ないけど、たまに電池切れちゃうときがあるのよね。
そうなるとかなり残念ですね。
電池が長持ちするのは、手間が減って本当にいいですね。