はじめに
- Elixir楽しんでいますか
- AndroidでSuicaの履歴をみるというものを作ってみました
- 「先頭から7bitが年、4ビットが月、残り5ビットが日」、「とある2バイトが残高、ただしリトルエンディアン」こういった処理って地味にけっこうたいへんではないでしょうか
- Elixirならパターンマッチですっきり書けますのでご紹介します
- 2021/2/27に開催するautoracex #12というもくもく会の成果とします
- 以下で紹介するサイトの記事を参考にするとすぐにできました
参考にしたサイト
- AndroidアプリでNFCタグを読み書きするための基礎知識
-
AndroidのNFCでSuicaの履歴を読んでみる
- 履歴を読み出すためのコマンドと取得例
-
https://github.com/thinkAmi/RubotoFelicaRead/blob/acccaa6f2a513154d25b7583061ac3e517be6c68/src/net/kazzz/felica/suica/Suica.java
- 「AndroidのNFCでSuicaの履歴を読んでみる」記事で省略されている処理の実装の参考になりそうなものが書いてあります
-
Felica Library > Wiki > Suica
- 履歴を読み出すためのコマンドを実行したあとに返ってくる値の仕様(構造)を有志の方がまとめてくださっています
( Felica Library > Wiki > Suica )
先頭から7bitが年、4ビットが月、残り5ビットが日
Java
public Date getProccessDate(int date, int time) {
int yy = date >> 9;
int mm = (date >> 5) & 0xf;
int dd = date & 0x1f;
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 2000 + yy);
c.set(Calendar.MONTH, mm-1);
c.set(Calendar.DAY_OF_MONTH, dd);
int hh = time >> 11;
int min = (time >> 5) & 0x3f;
c.set(Calendar.HOUR_OF_DAY, hh);
c.set(Calendar.MINUTE, min);
return c.getTime();
}
Elixir
-
"FgEAAilfAlyLByQDAAWHMA=="
は冒頭の写真でみせました表示例の最初のデータをBase64エンコードしたものであります - これを例に2020年10月31日が簡単に取り出せることを示します
iex> Base.decode64 "FgEAAilfAlyLByQDAAWHMA=="
{:ok, <<22, 1, 0, 2, 41, 95, 2, 92, 139, 7, 36, 3, 0, 5, 135, 48>>}
iex> <<_::32, year::7, month::4, day::5, _::binary>> = <<22, 1, 0, 2, 41, 95, 2, 92, 139, 7, 36, 3, 0, 5, 135, 48>>
<<22, 1, 0, 2, 41, 95, 2, 92, 139, 7, 36, 3, 0, 5, 135, 48>>
iex> year
20
iex> month
10
iex> day
31
- どうでしょうか、細かい書き方は抜きにして
7bit
とか4bit
、5bit
を指定することでパターンマッチで値をとれます - シフトなどの演算を自分で書く必要はありません
とある2バイトが残高、ただしリトルエンディアン
Java
remain = Long.valueOf((bytesToInt(new byte[]{response[24], response[23]})));
...
private int bytesToInt(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return Integer.valueOf(sb.toString(), 16);
}
- こちらも冒頭の写真の最初のデータの残高804円が取り出せる様子を示します
Elixir
iex> <<_::80, remain::16-little, _::binary>> = <<22, 1, 0, 2, 41, 95, 2, 92, 139, 7, 36, 3, 0, 5, 135, 48>>
<<22, 1, 0, 2, 41, 95, 2, 92, 139, 7, 36, 3, 0, 5, 135, 48>>
iex> remain
804
- どうでしょうか、こちらも
16-little
という文法さえ覚えてしまえばパターンマッチ一発で値を取得できます
Wrapping Up
(最後の最後に)Elixirってなによ? という方へ
- 2020/12/26時点くらいのスクリーンショット
- Elixirについてもっと知りたい方は下記の本をオススメします
-
elixir.jp Slackの
#autoracex
というところに私は入り浸っておりますのでお気軽にお声がけください -
勉強会が頻繁に行われています
- autoracex 【毎週月曜】
- Sapporo.beam 【毎週水曜】
- OkazaKirin.beam 【毎週木曜】
- fukuoka.ex/kokura.ex 【毎月2~3回】
- NervesJP 【毎月1回】