おサイフケータイなどのFeliCaのIDを読み取るJavaScript

おサイフケータイEdyとかSuicaとかに使われてるFeliCaJavaScriptで読み取ってみた。

普通のJavaScript(WSH)ではそんなこと出来ないので、いろいろ工夫した。

必要なもの

.NET Framework 2.0

これはいちいち説明しないけど、動作に必要なので入れておく。

FeliCaポート/パソリ

まずはコレがないと始まらない。USB接続でFeliCaを読み取れるパソリ。Amazonでも買える。

SONY RC-S320 非接触ICカードリーダ/ライタ PaSoRi 「パソリ」

SONY RC-S320 非接触ICカードリーダ/ライタ PaSoRi 「パソリ」

自分は昔ヨドバシでカード作ったら無料でもらった(初期型のやつ)。

FeliCaポートソフトウェア

FeliCaポートソフトウェアをインストールしておく。これが要はドライバらしい。

felicalibに含まれている「felicalib.dll」

felicalibをダウンロードして、zipを解凍するとその中に「felicalib.dll」というファイルが入ってる。このファイルを、適当なフォルダを作ってそこに置いておく。

これは普通のWindows用のdll。COMコンポーネントでもないし、.NETのdllでもない。

FelicaLibNET.dll

上記のfelicalib.dllをP/Invokeで.NETから呼び出せるようにするラッパーを作る。

felicalibに含まれてるC#のサンプルコードはexeを吐き出すものだったため、他の所から呼び出せない。新たに.NETのクラスライブラリプロジェクトを作って、サンプルコードのP/Invokeしてる部分(FelicaLib.cs)をコピペして、dllを生成した。

このファイルをダウンロードして、さっきのfelicalib.dllと同じフォルダに置いておく。

felica_id_reader.js

いよいよココがJavaScript。といっても、普通のJavaScriptではなく、JScript.NETJavaScriptで.NETのアプリが作れるアレだ。.NET Frameworkをインストールすれば、JScript.NETコンパイラも自動でインストールされる(と思う)。

以下、felica_id_reader.jsのコード。

import System;
import System.Threading;
import FelicaLibNET;

var f = new Felica();
while(true){
  try{
    f.Polling(0xffff);
    var bytes = f.IDm();
    var id = [];
    for(var i = 0; i < bytes.length; i++){
      id.push(Convert.ToString(Int32.Parse(bytes[i]), 16).PadLeft(2, '0'));
    }
    Console.Out.WriteLine(id.join(' '));
  }catch(e){
    //Console.Error.WriteLine(e.ToString());
  }
  Thread.Sleep(1000);
}

このコードをさっきのdllと同じフォルダに保存する。

そしてJScript.NETとしてコンパイルする。コマンドプロンプトを開いて、コードを保存したフォルダに移動し、以下のコマンドを打つ。

%windir%\Microsoft.NET\Framework\v2.0.50727\jsc felica_id_reader.js

コンパイルが成功すると、同じフォルダに「felica_id_reader.exe」が生成されるはず。

さっそく試してみる

これで準備完了。パソリをPCに接続して、felica_id_reader.exeを実行する。

1秒おきに読み取り動作を行って、その結果を出力する。FeliCa(おサイフケータイでもEdyのカードなどでも良い)をパソリの上に置くと、読み取ったIDを画面に表示するはず。

読み取ってる様子を動画で撮ってYouTubeにうpしてみた


  1. felica_id_reader.exeを起動
  2. おサイフケータイのIDを読み取らせる
  3. いったんケータイを持ち上げて、読み取らせない
  4. もう一度読み取らせる
  5. カード型のFeliCa(ヨドバシのポイントカード)のIDを読み取らせる

わかりにくいけど、ケータイから読んだIDと、カードから読んだIDは、ちゃんと違うものになっていた。他のケータイとかも試したけど、もちろんIDは全部違っていた。

すごい簡単だった

無理してJavaScriptで書こうとしたから苦労した部分もあったけど、普通にC#とかならもっと簡単に書けるはず。

要は、Felicaクラスをnewして、Pollingメソッドを読んで、IDmメソッドを呼ぶだけ。これでbyteの配列が返る。

例えば、会社のタイムカード代わりにFeliCaを読ませる、みたいなことができそう。社員IDとFeliCaのIDを紐付けておけば、FeliCaを読ませることで誰なのかがわかる。「所有による認証」って言うのかな。

これは、なにか特定のアプリケーションを使わず、FeliCaなら何でも良いのがミソ。おサイフケータイの人も、Edyの人もSuicaの人もその他カードの人も一緒に使える。「社員は全員、このカードを持ちなさい」みたいなのを強制しなくて良い。既に持ってるFeliCaならなんでも良い。

ID以外も読める

暗号化されてない部分、例えばEdySuicaの直近の利用履歴とかも取得できるっぽい。felicalibのサンプルコードが非常に参考になる。

おもしろかった

何か作りたいなあ。

追記 (2008.6.7)

パソリではなく、最初からFeliCaポートが内蔵されてるPCを持ってる友人が試してくれた。

それによると、FeliCaポートソフトウェアは導入する必要がなくて、felicalib.dllからの手順でうまく読めたらしい。

ただ、Suicaは読めなかったとのこと。あれ?と思って自分もSuica(view Suicaカード)で試してみたら、確かに読めない。反応が無い。felicalibに付属するサンプルのSuica読み出しプログラムはちゃんと動作するのに。まあいいや、なんとかなるでしょ。

追記 (2008.6.10)

id:FunnyBunnyDizzyさんからコメント欄で教えてもらった通り、

f.Polling(0xfe00);

の部分を

f.Polling(0xffff);

にしたらSuicaも読めた。0xfe00はFeliCa共通領域のコードで、Suicaはこれじゃ応答しない。0xffffはワイルドカードなので何でも応答するとのこと。上記のコードも0xffffに直した。