首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android NFC标签ID标识不同NFC卡类型

Android NFC标签ID标识不同NFC卡类型
EN

Stack Overflow用户
提问于 2020-10-23 17:36:43
回答 1查看 574关注 0票数 0

我想在我的应用程序中使用NFC读取,在那里我读取NFC卡的ID。我有两种不同的NFC卡。当我用我电脑中的USB NFC阅读器读取它们时,我得到了两张卡的9位数字,这很酷。我可以根据这个数字来识别卡片。

当我想要在我的应用程序中阅读它们时,问题就发生了,就像这样:

代码语言:javascript
复制
                            new NfcAdapter.ReaderCallback() {
                                @Override
                                public void onTagDiscovered( final Tag tag ) {
                                    runOnUiThread(new Runnable() {

                                        @Override
                                        public void run() {
                                            System.out.println(tag.toString());

                                            // I get the ID here to identify the card
                                            String id = Long.toString(Utils.toDec(tag.getId())).trim();
                                        }
                                    });

                                }
                            },
                            1 | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
                            options);

当我记录所发现的标签的toString()方法时,我得到了第一张卡的如下信息:

代码语言:javascript
复制
Tech [android.nfc.tech.NfcA, android.nfc.tech.MifareClassic]

当我读取String id = Long.toString(Utils.toDec(tag.getId())).trim();下面的ID时,我得到了与我的计算机中相同的9位数字,这太棒了,它是卡的唯一id。

第二张卡的toString()

代码语言:javascript
复制
Tech [android.nfc.tech.IsoDep, android.nfc.tech.NfcA]

当我读取标签ID时,我得到的是17位数字,而不是9位数字...我试着在发现的标签中记录所有的东西,但是我找不到我可以通过USB阅读器从计算机的卡中读取的9位数字。所以我无法识别这张NFC卡。

我该如何解决这个问题呢?我想通过USB阅读器和我的应用程序识别卡,所以2个数字必须相同,就像第一张卡一样…

谢谢!:)

EN

回答 1

Stack Overflow用户

发布于 2020-10-23 21:54:12

因此,根据该卡的数据表https://www.nxp.com/docs/en/data-sheet/MF3DX2_MF3DHX2_SDS.pdf的7.4节(以及亚马逊列表),该卡的UID是一个7字节的UID。

因此,它不是一种为了兼容而具有多个ID的卡,但它所使用的标准确实允许4,7,10字节的UID,请参阅http://emutag.com/iso/14443-3.pdf标准的第19页

根据ISO 1444-3标准,较大的UID被分成多个部分发送,数据表

根据ISO/IEC 14443-3的

在第一防冲突循环期间,级联标签向UID2和BCC返回88h的值以及UID、UID0的前3个字节。第二个防冲突循环将字节UID3返回给UID6和BCC

在应用笔记https://www.nxp.com/docs/en/application-note/AN10927.pdf中解释了该过程和问题

因此,在应用笔记3.2部分

在某些情况下,阅读器基础设施可能能够处理双倍大小的UID,但(后台)系统只能处理4字节的UID。反之亦然,读取器基础设施可能无法处理双倍大小的UID,但(后台)系统需要唯一性,并且可以处理双倍大小的UID。

因此,USB读取器和运行它的代码可能执行了错误的防冲突,因为它无法处理它返回的4Byte UID以外的内容,它可能不会响应卡返回的数据并处理级联标记位(因此它实际上可能只返回7字节UID的前3个字节。

您没有提供所使用的USB读卡器的详细信息(制造商和型号),也没有提供用于读取它的源代码或应用程序的详细信息,因此无法查看它是否可以返回正确大小的UID。

但应用笔记附录6给出了将7字节UID转换为4字节UID的代码(不幸的是,这不是用C编写的,但您应该能够将其转换为Java ),但USB读取器可能也会返回正确的4字节UID,因此这可能没有帮助。

此外,为了更好地进行诊断,将值打印为十六进制而不是十进制,因为这样可以更好地告诉您发生了什么。

添加了

一种将字节数组转换为可打印十六进制字符串https://stackoverflow.com/a/332101/2373819的方法

此外,如果您提供了来自卡的实际UID值的更多信息,则可能会看到USB读取器是如何出错的(即UID 88h的第一个字节?)

更新说明其他卡很容易看到,这是一个Mifare经典,像EV1这样的新版本也有一个7字节的UID (非常旧的型号有一个4字节的UID),所以也应该显示更大的十进制的UID (如果是像EV1版本的现代卡),但这也有一个4字节的UID作为前4个字节的7个字节,以兼容较老的版本。

因为您正在使用通用的Tag Technology类型读取UID,所以它可能会将其截断为4个字节,或者它可能是一个旧版本。在使用getID之前,尝试在正确的特定类中获取标记。

代码语言:javascript
复制
MifareClassic mMifareClassic = MifareClassic.get(tag);
byte[] uid = mMifareClassic.getID();

您可以使用switch tag.getTechList();为每种类型的标记使用正确的标记技术类

或者尝试读取Block 0以直接获取UID。

摘要

问题是,当卡只有恩智浦Mifare Desfire卡的7字节UID时,USB读卡器给出的似乎是4字节的UID。

在MifareClassic卡上,它应该是7字节UID的前4个字节,因为这是较新的7字节UID卡被设计为与旧的4字节UID卡兼容,因此您可以取阵列的一部分来使它们匹配。

在恩智浦Mifare Desfire卡上

A)第一个防冲突命令中的4个字节?(这将包括级联标签88h值)

B) 7字节UID的前4个字节?所以再一次,你可以取一片来使它们匹配。

备注

这些值的某些表示首先给出最高有效位,而不是最低有效位。

例如,从您的注释中可以看出,其中一个长UID是十进制的36125410196403972,也就是十六进制的8057DE821F3704,但是数据手册中说最低有效字节应该是04,表示恩智浦是制造商,但正如您在8057DE821F37中看到的那样,04颠倒了过来,最高有效位在前,最低有效位在后。

因此,您可以尝试并尝试只取前4个字节的组合,看看是否能使它们全部匹配。

或者让USB读卡器为两张卡读取正确的完整7字节UID (因为仅使用4字节并不能保证唯一性(即使是7字节UID或任何大小的UID也不能用于唯一性和安全性,因为它们太容易被伪造)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64497556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档