2009/07/07
■ [felica] pasori を使って fcf フォーマットから ID,氏名を抽出する
私の職場の ID カードは 1 年ほど前から非接触型のカードになりました.
職場の知り合いから「カードから ID と氏名を抜き出すプログラムを作って」と言われたので,さっそく USB 接続のリーダ pasori を買って試してみました.ここではその方法をまとめておきます.私は cygwin + Windows XP で試しました.
調べてみると,felicalib を使ってカードの情報が dump できるらしいので, felicalib を入れてみました.
felicalib と一緒に配布されている FelicaDump.exe を cygwin 経由で実行すると,下記のようになぜか失敗しました.
% ./FelicaDump.exe Polling card failed.
Windows 上のコマンドプロンプトで FelicaDump を実行すると,出力されたので環境変数を調べてみると,下記を PATH に入れていないと FelicaDump は実行できませんでした. felicalib は felica.dll を叩くと書いてあったので felica.dll が PATH に入っていないとダメでしたね.
# FelicaDump を実行するには下記を PATH に追加する必要あり /cygdrive/c/Program Files/Common Files/Sony Shared/FeliCaLibrary
felica.dll の場所を PATH に入れると下記のように無事カードの情報を取得することができました.
% ./FelicaDump.exe # IDm: 01 XX XX XX XX XX XX XX # PMm: XX XX XX XX XX XX XX XX # System code: 80DE # Number of area = 9 # Area: 0000 - FFFE # Area: 0040 - 07FF # Area: 0800 - 0FBF # Area: 0FC0 - 7FFF # Area: 1000 - 17BF # Area: 17C0 - 7FFF # Area: 3380 - 33BF # Area: 8000 - FFFE # Area: C800 - C83F # Number of service code = 33 # Serivce code = 0048 : Random Access R/W (Protected) # Serivce code = 004A : Random Access Read only (Protected) 004A:0000 00 FF XX XX XX XX XX XX XX XX XX XX XX XX XX XX (snip) ..........
次はここから ID と氏名の抽出なのですが,felica fcf のフォーマットであることはわかっているのですが,どこにどのように入っているかさっぱりわかりません.FCF Felica 共通利用フォーマット 推進フォーラムを見ても技術的なことは一切ないので困りました.
とりあえず下記のようなコードを書いて,全サービスコードの値を出力したのですがどうも ID と氏名はありません.
#!/usr/bin/env perl # hoge.pl # usage: # FelicaDump.exe | hoge.pl use strict; use Data::Dumper; while (<STDIN>) { if (.{4}:.{4} (.*)/) { my $buf = $1; my @buf = split /\s/, $buf; my $value = pack ("H*", @buf); print Dumper $value; } }
カードに関するもう少し細い仕様をもらおうかなと考えていたときに,他のひとのデータと差分を取れば,どこが ID で氏名なのかがわかると思い,他人のカードを借りてその人のデータを FelicaDump で出力しました.
私のカードの情報と他人の情報を diff で比較すると,何か所か ID と氏名だけの差分じゃないかと思える Service code がわかりました.
# Serivce code = 090F : Cyclic Access Read only -090F:0000 19 07 00 00 XX XX XX XX 00 00 00 00 00 00 XX C0 +090F:0000 19 07 00 00 XX XX XX XX 00 00 00 00 00 00 XX C0 @@ -6469,1037 +6469,1037 @@ # Serivce code = 1A8B : Random Access Read only -1A8B:0000 XX 31 XX XX XX XX XX XX XX XX 00 00 00 00 XX XX -1A8B:0001 XX XX XX XX XX XX 00 00 00 00 00 00 00 00 00 00 +1A8B:0000 XX 31 XX XX XX XX XX XX XX XX 00 00 00 00 XX XX +1A8B:0001 XX XX XX XX XX XX XX 00 00 00 00 00 00 00 00 00
ということで Service code 1A8B の 0001 と 0002 について,下記のように pack してみると...
# $str には XX XX XX XX XX XX XX 00 00 00 00 00 00 00 00 00 # みたいな値が入ってます my @data = split /\s+/, $str; for (my $i = 0; $i < @data; $i++) { $name .= pack "H2", $data[$i] if ($data[$i] ne '00'); }
無事 ID と氏名が抽出できました.私の職場では氏名はなぜか半角仮名で入っていました...
% perl felica-dump.pl ./myid-dump.txt |nkf -e $VAR1 = 'XXXXXX54'; $VAR2 = 'ホリ ナマエ';
関連リンク
- FCF Felica 共通利用フォーマット 推進フォーラム http://www.fcf.jp/
- felicalib http://felicalib.tmurakam.org/