Aizu-Progressive xr Lab blog

会津大学のVR部であるA-PxLの部員が持ち回りで投稿していくブログです。部員がそれぞれVRに関する出来事やVRにちなんだことについて学んだことを書いていきます。

連絡はサークルTwitterのDMへお願いします。
「面白法人カヤックVR分室」としても活動しています。詳細はこちら

nfcpyを使って学生証から学籍番号を読み取る

こんにちは。A-PxL元代表の橋本です。先日の集会を最後に代表を引退することになりました。1年と半年、振り返ってみれば楽しいこと、辛いこと、うれしいことが色々ありましたが、どれもいい思い出たちばかりです。

さて、今週は私がブログ当番なので私の最近の話をしようと思います。内容は、学生証から学籍番号を読み取ったことについてです。

目次

動機

会津大では、毎年4月に新入生が入ってくると新入生のために歓迎会を開くことが通例となっており、この機会を使って上級生は新入生に向けて自身が所属するサークルの勧誘活動を行なっております。各サークルはブースを設けており、そこに新入生が行って内容を聞くということをしてます。そして、気になったサークルがあれば、そこのブースにある 紙の名簿に自身の学籍番号と名前を書き込みます。この名簿に書かれた学籍番号を使ってサークル関係者は学内メールを通してサークルの説明会や体験会についての連絡を新入生にするわけですね。

問題なのは、紙の名簿だということです。 メールを送信する際には、紙に書かれた学籍番号をPCに手打ちする作業が出てきます。書き込んでくれた学生が少ない場合は問題ないのですが、多いとそれだけ苦労するというわけです。2018年度の新歓では私たちの部にはなんと50名もの新入生が名簿に記入してくれました。嬉しかったのですが、その後の50人分の学籍番号の手打ち作業はとても辛かったですね(笑)

ということで、この手打ち作業をなくすべく、何かシステムを作らねば! というのが今回このシステムを作ろうと思ったきっかけです。

要件

個人的にNFCリーダーを使った何かをすることに興味がありました。そこで、学生証から学籍番号を読み取ることを考えました。また、読み取ったデータはスプレッドシートに書き込まれるようにするのがいいかと考え、読み込んだ学籍番号はGoogle Spread Sheetに書き込まれるようにしました。さらに、せっかくうちの部ではUnityを使ったアプリ開発を行なっているので、どうせなら読み込まれた学籍番号をUnity上で少し演出を加えて表示させようと思い、この実装も行うことにしました。(最後の1つはシステム的には蛇足ですけどね(笑))

f:id:aizu-vr:20190802165529p:plain

実は、この作品は私が大学で受けていた授業の最終プロジェクトとして作ったものです。そのプロジェクトは、ラズパイを使って何かしよう! というものでした。そのためこのシステムではラズパイを用いております。

今回はICカードリーダー周りについて書いていきます。

NFCFelicaについて

NFCとは、Near Field Communicationの略で、かざすことデータ交換をするために規定された近距離無線通信技術です。そして、FelicaNFCの規格をもとにしてSONYが作った規格です。特徴として、Felicaは通信速度が速く、NFCの2倍ほどと言われています。そのこともあって、日本国内では主にFelicaが使われることが多いです。SuicaPasmo, nanacoカード、WAONカードなどはすべてFelicaです。

詳しくはこちらの記事をお読みください。

[PASMO] FeliCa から情報を吸い出してみる - FeliCaの仕様編 [Android][Kotlin] - Qiita

学籍番号を読み取る

学籍番号を読み取るには読み取るための装置が必要です。手元になかったので買いました。ネットで色々調べた結果、以下の装置を購入しました。

ソニー SONY 非接触ICカードリーダー/ライター PaSoRi RC-S380

ソニー SONY 非接触ICカードリーダー/ライター PaSoRi RC-S380

意外と安く手に入るものなんですね。

さて、準備も整ったので、早速読み取ってみましょう。まずは環境を整えます。以下の記事を参考にして整えてみてください。

RaspberryPiで!SONYのPaSoRi(RC-S380)で(NFC)Felica情報を読み取る! - KOKENSHAの技術ブログ

次に、カードのどこの部分に学籍番号が書かれているかを知らなければなりません。そこで、ダンプしてカードの中のどこに学籍番号情報があるかを確認します。

コードはこちらの方のものを使わせていただきました。

Raspberry Pi 3にPaSoRiを接続してSuicaカードをダンプする | TomoSoft

会津大の学生証をダンプした結果

System 809E (unknown)
Area 0000--FFFE
  Area 1000--1FFF
    Random Service 64: write with key (0x1008)
    Random Service 68: write with key (0x1108)
    Random Service 72: write with key (0x1208)
    Random Service 76: write with key (0x1308)
    Random Service 128: write with key (0x2008)
    Area 3000--3FFF
    Random Service 192: write with key & read w/o key (0x3008 0x300B)
     0000: 31 30 30 30 31 32 35 3X 3X 3X 3X 30 30 30 30 30 |1000125XXXX00000|
System FE00 (Common Area)
Area 0000--FFFE
  Area 1A80--1AFF
    Area 1A81--1AFF
      Random Service 106: write with key & read w/o key (0x1A88 0x1A8B)
       0000: 30 31 30 30 31 32 35 3X 3X 3X 3X 00 00 00 30 31 |0100125XXX...01|
       0001: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
       0002: 30 3X 30 3X 3X 3X 3X 3X 3X 30 3X 3X 30 3X 30 3X |0X0XX0XXX0XX0X01|
       0003: 3X 30 3X 3X 30 3X 3X 31 3X 30 30 30 30 30 3X XX |X0XX0XXXX00000XX|
      Area 1BXX--1BXX
      Area 1XXX--1BXX
        Random Service 108: write with key & read with key (0x1BXX 0x1BXX)
        Area 1XXX--1BXX
        Area 1BXX--1B7F
          Random Service 109: write with key & read with key (0xXX48 0xXX4A)
          Area 4XX0--42XX
          Area 4XX1--42XX
            Random Service 267: write with key & read with key (0xXXC8 0x4XXX)
            Area X3X0--4X3F
            Area X30X--4X3F
              Random Service 268: write with key & read with key (0x43XX 0x4XXX)
              Area XXXX--43XX
              Area 43XX--4XX7
                Random Service 269: write with key & read w/o key (0x43XX 0xXX4B)
                 0000: 00 XX 00 00 XX 00 XX 00 XX 00 XX 00 XX 00 XX XX |................|
                 *     00 XX 00 XX 00 XX 00 XX 00 XX 00 XX 00 00 XX XX |................|
                 000X: 0X 0X 00 XX 00 00 XX 00 XX 00 XX XX 00 00 00 00 |................|

データ保護のためところどころにXを入れています。

どうやら、システム809Eのサービスコード0x300Bに学籍番号らしきものがあるようですね。この値を使って学籍番号を読み取ってみたいと思います。Pythonコードを書いていきます。

こちらの記事を参考にしました。

nfcpy で複数の System Code を持つ NFC タグを扱う方法 - uchan note

#!/usr/bin/env python
# -*- coding: utf-8 -*-
  
import binascii
import nfc
import time

# 学生証のサービスコード
service_code = 0x300B

def on_connect_nfc(tag):
  # タグのIDなどを出力する
  # print tag
  
  if isinstance(tag, nfc.tag.tt3.Type3Tag):
    try:
        sc = nfc.tag.tt3.ServiceCode(service_code >> 6 ,service_code & 0x3f)
        bc = nfc.tag.tt3.BlockCode(0,service=0)
        data = tag.read_without_encryption([sc],[bc])
        sid =  "s" + str(data[4:11])
        print sid
    except Exception as e:
      print "error: %s" % e
  else:
    print "error: tag isn't Type3Tag"
  
def main():
  clf = nfc.ContactlessFrontend('usb')
  while True:
    clf.connect(rdwr={'on-connect': on_connect_nfc})
    time.sleep(3)
  
if __name__ == "__main__":
  main()

このコードを使うことで会津大の学生証から学籍番号を読み取ることができます。このプログラムでは3秒毎に学生証の学籍番号を読み取ってコンソールに表示させています。

f:id:aizu-vr:20190802184316p:plain

まとめ

最初は難しいのかなと思っていたのですが、思ったほど難しくはなかったですね。先駆者様の方々のおかげです。今回はラズパイを使ったこともありPythonを使用しましたが、調べてみたところ、C#にもNFCを扱うライブラリがあるそうなので、時間があったらやってみたいと思ってます。

来年の新歓はこれで少しは楽になるといいなぁ〜

会津大学VR部の部員が持ち回りで投稿していくブログです。特にテーマに縛りを設けずに書いていきます!