Android NFC相关资料之MifareClassic卡(读写)

电子专业 徐 自远 690℃ 0评论

Android NFC相关资料之MifareClassic卡(读写)

from: http://wszf.net/archives/2012/11/07/80510.html

一般来说,给予MifareClassic的射频卡,一般内存大小有3种:

1K: 16个分区(sector),每个分区4个块(block),每个块(block) 16个byte数据

2K: 32个分区,每个分区4个块(block),每个块(block) 16个byte数据

4K:64个分区,每个分区4个块(block),每个块(block) 16个byte数据

对于所有基于MifareClassic的卡来说,每个区最后一个块叫Trailer,16个byte, 主要来存放读写该区的key,可以有A,B两个KEY,每个key长6byte,默认的key一般是FF 或 0,最后一个块的内存结构如下:

Block 0  Data 16bytes

Block 1  Data 16 bytes

Block 2  Data 16 bytes

Block 3  Trailer 16 bytes

Trailer:

Key A: 6 bytes

Access Conditions: 4 bytes

Key B: 6 bytes

M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成,(我们也将16个扇区的64个块按绝对地址编号为0~63,)存贮结构如右表所示

         



0

0

 

数据块

0

1

 

数据块

1

2

 

数据块

2

3

密码A  存取控制  
 密码B

数据块

3



1

0

 

数据块

4

1

 

数据块

5

2

 

数据块

6

3

密码A  存取控制  
 密码B

数据块

7

   



 

   



15

0

 

数据块

60

1

 

数据块

61

2

 

数据块

62

3

密码A  存取控制  
 密码B

数据块

63

 

0扇区的块0(即绝对地址0块),它用于存放厂商代码,已经固化,不可更改。

每个扇区的块0、块1、块2为数据块,可用于存贮数据。

每个扇区的块3为控制块,包括了密码A、存取控制、密码B。具体结构如下:

A1A2 A3 A4 A5               FF 07 8069               B0 B1 B2 B3 B4 B5

密码A6字节)          存取控制(4字节)          密码B6字节)  

每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制;

存取控制为4个字节,共32位,扇区中的每个块(包括数据块和控制块)的存取条件是由密码和存取控制共同决定的。
工作原理:

读写器向M1卡发一组固定频率的电磁波,卡片内有一个LC串联谐振电路,其频率与讯写器发射的频率相同,在电磁波的激励下,LC谐振电路产生共振,从而使电容内有了电荷,在这个电容的另一端,接有一个单向导通的电子泵,将电容内的电荷送到另一个电容内储存,当所积累的电荷达到2V时,此电容可做为电源为其它电路提供工作电压,将卡内数据发射出去或接取读写器的数据。

Android 读写M1

先了解一下MifareClassic协议

在android sdk 的文档中,描述道 “all MifareClassic I/O operations will be supported, and MIFARE_CLASSIC NDEF tags will also be supported. In either case, NfcAwill also be enumerated on the tag, because all MIFARE Classic tags are also NfcA.” 所以说NFCA协议是兼容MifareClassic 协议的, 我们可以通过NfcA在android的相关类来处理给予MifareClassic 的RFID卡。

读M1卡代码:

01

if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action))

02

                    {

 

03

                        // 3) Get an instance of the TAG from the NfcAdapter

04

                        Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

 

05

                        // 4) Get an instance of the Mifare classic card from this TAG

06

                        // intent

 

07

                        mfc = MifareClassic.get(tagFromIntent);

08

                        if(mfc!=null)

 

09

                            {

10

                                Toast.makeText(this, “检测到卡片,读卡中。。。”, Toast.LENGTH_SHORT).show();

 

11

                                try

12

                                    {

 

13

                                        mfc.connect();

14

                                        boolean auth = false;

 

15

                                         auth = mfc.authenticateSectorWithKeyA(15, “passwo”.getBytes());//验证密码

16

                                         if (auth)

 

17

                                             {

18

                                                 card_number_edittext.setText(new String(mfc.readBlock(60)));//读取M1卡的第60块即15扇区第0块

 

19

                                                                 password_edittext.requestFocus();

20

                                             }

 

21

                                    } catch (Exception e)

22

                                    {

 

23

                                        if(BuildConfig.DEBUG)

24

                                            {

 

25

                                                e.printStackTrace();

26

                                            }

 

27

   

28

                                    }

 

29

                            }

30

                    }// End of method

写M1卡代码:

01

try

02

    {

 

03

        mfc.connect();

04

        boolean auth = false;

 

05

        short sectorAddress = 1;

06

        auth = mfc.authenticateSectorWithKeyA(sectorAddress, MifareClassic.KEY_DEFAULT);

 

07

        if (auth)

08

            {

 

09

                // the last block of the sector is used for KeyA and KeyB cannot be overwritted

10

                mfc.writeBlock(4, “1383838438000000”.getBytes());//必须为16字节不够自己补0

 

11

                mfc.close();

12

                Toast.makeText(MainActivity.this, “写入成功”, Toast.LENGTH_SHORT).show();

 

13

            }

14

    } catch (IOException e)

 

15

    {

16

        // TODO Auto-generated catch block

 

17

        e.printStackTrace();

18

    } finally

 

19

    {

20

        try

 

21

            {

22

                mfc.close();

 

23

            } catch (IOException e)

24

            {

 

25

                // TODO Auto-generated catch block

26

                e.printStackTrace();

 

27

            }

28

    }

Demo下载地址:NFCDemo

参考资料:1/2/3/4/5

转载请注明:徐自远的乱七八糟小站 » Android NFC相关资料之MifareClassic卡(读写)

喜欢 (0)

您必须 登录 才能发表评论!

苏ICP备18041234号-1 bei_an 苏公网安备 32021402001397号