はじめに
開志専門職大学の学生証からnfcpyを使用して氏名と学籍番号を読み取るプログラムを作成しました。
NFCリーダー
- RC-S380/S
- 対応OS : win10,win11
環境構築
-
Zadigのダウンロード
-
Zadigを使用して、ドライバーの置換
- optionからList All Devicesを選択し、riverをWinUSBに変更後Replace Driverをクリック
-
libusbの導入
- https://libusb.info/
- DownloadsからLatest Windows Binariesをクリックすることでダウンロードすることができる
-
VS2015-x64\dll\libusb-1.0.dll
をC:\Windows\System32
に配置 -
VS2015-Win32\dll\libusb-1.0.dll
をC:\Windows\SysWOW64
に配置
-
nfcpyのインストール
pip install nfcpy
python環境
- python 3.11.6
- requirements.txt
libusb1==3.1.0 ndeflib==0.3.3 nfcpy==1.0.4 pyDes==2.0.1 pyserial==3.5
学生証を読み取る
-
NFCを読み取り、表示するプログラム
nfc_dump.pyimport nfc def on_connect(tag: nfc.tag.Tag) -> None: print("\n".join(tag.dump())) with nfc.ContactlessFrontend("usb") as clf: clf.connect(rdwr={"on-connect": on_connect})
-
出力
nfc_dump.pyの出力System 809E (unknown) Area 0000--FFFE Area 1000--11FF Random Service 64: write with key & read with key (0x1008 0x100A) Area 1200--12FF Random Service 72: write with key & read with key (0x1208 0x120A) Cyclic Service 72: write with key & read with key (0x120C 0x120E) Purse Service 72: direct with key & cashback with key & decrement with key & read with key (0x1210 0x1212 0x1214 0x1216) Random Service 73: write with key & read with key (0x1248 0x124A) Random Service 74: write with key & read with key (0x1288 0x128A) Random Service 700: write with key & read w/o key (0xAF08 0xAF0B) 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| Random Service 701: write w/o key (0xAF49) 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 002D: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 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: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX |XXXXXXXXXXXXXXXX| 0001: 83 4e 83 89 83 43 83 56 81 40 83 5e 83 43 83 4c |.N...C.V.@.^.C.L| 0002: 31 35 30 31 32 33 39 34 32 30 32 32 30 34 30 31 |1501239420220401| 0003: 32 30 32 36 30 33 33 31 41 48 32 38 30 33 33 39 |20260331AH280339| Area 1B00--1B3F Area 1B01--1B3F Random Service 108: write with key & read with key (0x1B08 0x1B0A) Area 1B40--1B7F Area 1B41--1B7F Random Service 109: write with key & read with key (0x1B48 0x1B4A) Area 42C0--42FF Area 42C1--42FF Random Service 267: write with key & read with key (0x42C8 0x42CA) Area 4300--433F Area 4301--433F Random Service 268: write with key & read with key (0x4308 0x430A) Area 4340--437F Area 4341--437F Random Service 269: write with key & read w/o key (0x4348 0x434B) 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 0002: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| Area 7A00--7A3F Area 7A01--7A3F Random Service 488: write with key & read with key & read w/o key (0x7A08 0x7A0A 0x7A0B) 0000: 33 39 32 31 30 31 30 30 31 30 36 37 35 39 34 39 |3921010010675949| Area 7A40--7A7F Area 7A41--7A7F Random Service 489: write w/o key & read w/o key (0x7A49 0x7A4B) 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000B: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
- ※学籍番号の部分はXXに変更
-
ダンプされたデータをみると以下の箇所に目当てのデータが格納されていそうです
Random Service 106: write with key & read w/o key (0x1A88 0x1A8B) 0000: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX |XXXXXXXXXXXXXXXX| 0001: 83 4e 83 89 83 43 83 56 81 40 83 5e 83 43 83 4c |.N...C.V.@.^.C.L| 0002: 31 35 30 31 32 33 39 34 32 30 32 32 30 34 30 31 |1501239420220401| 0003: 32 30 32 36 30 33 33 31 41 48 32 38 30 33 33 39 |20260331AH280339|
- ※学籍番号の部分はXXに変更
NFCの構造
-
write with key & read with key & read w/o key
- ダンプされたデータを見るとところどころに英単語が見受けられます
操作 説明 write with key
鍵を使用して書き込むことが可能 read with key
鍵を使用して読み込むことが可能 read w/o key
データを読み取るために暗号鍵は不要で、鍵なしでアクセス可能
-
NFCに格納されたデータをプログラムで読み込むためには、以下を指定する必要があります。
- システムコード
- サービスコード
- ブロックコード
-
目当てのデータを読み込む場合
- システムコード :
0xFE00
System FE00 (Common Area)
- サービスコード :
0x1A8B
Random Service 106: write with key & read w/o key (0x1A88 0x1A8B)
- 今回は、
read w/o key
を使用して読み取るので、0x1A8B
を使用します
- 今回は、
- ブロックコード :
0
,1
,2
,3
0000: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX |XXXXXXXXXXXXXXXX| 0001: 83 4e 83 89 83 43 83 56 81 40 83 5e 83 43 83 4c |.N...C.V.@.^.C.L| 0002: 31 35 30 31 32 33 39 34 32 30 32 32 30 34 30 31 |1501239420220401| 0003: 32 30 32 36 30 33 33 31 41 48 32 38 30 33 33 39 |20260331AH280339|
- システムコード :
氏名と学籍番号を抜き出す
-
氏名と学籍番号を抜き出すプログラム
extract_student_info.pyimport nfc from typing import cast def on_connect(tag): sys_code = 0xFE00 service_code = 0x1A8B idm, pmm = tag.polling(system_code=sys_code) tag.idm, tag.pmm, tag.sys = idm, pmm, sys_code sc = nfc.tag.tt3.ServiceCode(service_code >> 6, service_code & 0x3F) # student_num bc = nfc.tag.tt3.BlockCode(0, service=0) student_num = cast(bytearray, tag.read_without_encryption([sc], [bc])) student_num = student_num.decode("shift_jis") print("student number : " + str(student_num)) # name bc = nfc.tag.tt3.BlockCode(1, service=0) name = cast(bytearray, tag.read_without_encryption([sc], [bc])) name = name.decode("shift_jis") print("name : " + str(name)) with nfc.ContactlessFrontend("usb") as clf: clf.connect(rdwr={"on-connect": on_connect})
-
出力
extract_student_info.pyの出力student number : 20122XXX name : クライシ タイキ
- ※学籍番号の部分はXXに変更
- 学籍番号と氏名(カタカナ)が出力されました。
-
プログラムの説明
-
on_connect
関数- NFCタグが接続された時に呼び出されます
- システムコードとサービスコードの指定
sys_code = 0xFE00 service_code = 0x1A8B
- システムコードの切り替え
- 複数のシステムコードを持つ場合は、
polling
を使用してシステムコードを切り替えます。
idm, pmm = tag.polling(system_code=sys_code) tag.idm, tag.pmm, tag.sys = idm, pmm, sys_code
- 複数のシステムコードを持つ場合は、
- データの読み取り後、
bytearray
型に変換student_num = cast(bytearray, tag.read_without_encryption([sc], [bc]))
- デコード
- このNFCは、
shift_jis
でエンコードされていました
student_num = student_num.decode("shift_jis")
- このNFCは、
-
まとめ
- 学籍番号と氏名は以下のアドレスに格納されています。開専門職大学の学生証を使う方に参考になるとうれしいです。
- 学籍番号
- システムコード : 0xFE00
- サービスコード : 0x1A8B
- ブロックコード : 0
- 氏名(カタカナ)
- システムコード : 0xFE00
- サービスコード : 0x1A8B
- ブロックコード : 1
- 学籍番号
- ブロックコード2,3には、入学年月日と卒業予定年月日が格納されていましたが、今回の目当てではないので省略させていただきました。
- これを使って、入退室の管理システムを作れたらいいなと思います。
参考文献