簡體   English   中英

Android NFC 標簽 ID 識別不同的 nfc 卡類型

[英]Android NFC tag ID identify different nfc card type

我想在我的應用程序中使用 NFC 讀取,在那里我讀取了 NFC 卡的 ID。 我有 2 張不同的 NFC 卡。 當我用我的電腦中的 USB NFC 閱讀器讀取它們時,我得到了兩張卡的 9 位數字,這很酷。 我可以根據那個數字識別卡片。

當我想在我的應用程序中閱讀它們時,就會出現問題,如下所示:

                            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);

當我記錄發現的 TAG 的toString()方法時,我得到了第一張卡片的信息:

Tech [android.nfc.tech.NfcA, android.nfc.tech.MifareClassic]

當我閱讀下面的 ID String id = Long.toString(Utils.toDec(tag.getId())).trim(); 我得到了和我的電腦一樣的 9 位數字,太好了,它是卡的唯一 ID。

第二張卡片的toString()

Tech [android.nfc.tech.IsoDep, android.nfc.tech.NfcA]

當我讀取標簽 ID 時,我得到一個 17 位數字而不是 9 位數字......我試圖在發現的 TAG 中記錄所有內容,但我無法在我的卡片中找到我可以從該卡讀取的 9 位數字電腦通過USB閱讀器。 所以我無法識別這張NFC卡。

我該如何解決這個問題? 我想通過 USB 讀卡器和我的應用程序識別卡,所以這兩個數字必須相同,就像第一張卡一樣......

謝謝! :)

因此,根據其數據表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,在第一個防沖突循環期間,級聯標簽返回值 88h 以及 UID 的前 3 個字節,UID0 到 UID2 和 BCC。 第二個防沖突循環返回字節 UID3 到 UID6 和 BCC

在應用筆記https://www.nxp.com/docs/en/application-note/AN10927.pdf中解釋了過程和問題

所以在應用筆記第 3.2 節中

在某些情況下,閱讀器基礎設施可能能夠處理雙倍大小的 UID,但(后台)系統只能處理 4 字節的 UID。 反之亦然,閱讀器基礎設施可能無法處理雙倍大小的 UID,但(后台)系統需要唯一性並且可以處理雙倍大小的 UID。

因此,USB 讀取器和運行它的代碼可能會做防沖突錯誤,因為它無法處理超過它返回的 4 字節 UID,它可能不會響應卡返回的數據並處理級聯標記位(所以它實際上可能只返回 7 字節 UID 的前 3 個字節。

您沒有提供所使用的 USB 讀取器(品牌和型號)或用於讀取它的源代碼或應用程序的詳細信息,因此無法幫助查看它是否可以返回正確大小的 UID。

但是 Application Note Append 6 給出了將 7 字節 UID 轉換為 4 字節 UID 的代碼(不幸的是,這是在 C 而非 Java 中,但您應該能夠將其轉換為 Java)但 USB 讀取器可能會返回正確的 4 字節 UID同樣,所以這可能無濟於事。

同樣為了更好的診斷,將值打印為十六進制而不是十進制,因為這會更好地告訴您發生了什么。

添加
一種將字節數組轉換為可打印十六進制字符串的方法https://stackoverflow.com/a/332101/2373819

此外,如果您提供有關卡中實際 UID 值的更多信息,則可能會看到 USB 讀取器是如何出錯的(即 UID 88h 的第一個字節?)

更新說明其他卡很容易看到它是 Mifare Classic,其中較新的版本如 EV1 也有一個 7 字節的 UID(非常舊的型號有一個 4 字節的 UID)所以也應該顯示更大的十進制 UID(如果像EV1 版本)但是這也有一個 4 字節 UID 作為與舊版本兼容的 7 個字節的前 4 個字節。

因為您正在使用通用標簽技術類型讀取 UID,所以它可能會將其截斷為 4 個字節,或者它可能是舊版本。 在使用getID之前嘗試在正確的特定類中獲取標簽,例如

MifareClassic mMifareClassic = MifareClassic.get(tag);
byte[] uid = mMifareClassic.getID();

你可以使用 switch tag.getTechList(); 為每種類型的標簽使用正確的標簽技術類

或嘗試讀取Block 0以直接獲取 UID。

概括
問題是當卡只有 7 字節的 UID 時,USB 讀卡器給出的似乎是 4 字節的 UID。

在 MifareClassic 卡上,它應該是 7 字節 UID 的前 4 個字節,因為這是較新的 7 字節 UID 卡被設計為與舊的 4 字節 UID 卡兼容,因此您可以取數組的一部分使它們匹配.

在 NXP Mifare Desfire 卡上

A) 第一個防沖突命令的 4 個字節? (這將包括級聯標簽 88h 值)

B) 7 字節 UID 的前 4 個字節? 所以你可以再切片讓它們匹配。

筆記
這些值的某些表示首先給出最高有效位而不是最低有效位。

例如,從您的評論的長UID的一個是36125410196403972十進制這是8057DE821F3704十六進制但數據表說,至少顯著字節應該是04識別恩智浦作為制造商,但你可以從8057DE821F37看到04被扭轉為最顯著位在前,最低位在后。

因此,您可以嘗試嘗試只取前 4 個字節的組合,並進行反轉和不反轉,看看是否可以讓它們全部匹配。

或者讓 USB 讀卡器讀取兩張卡的正確完整 7 字節 UID(因為僅使用 4 字節並不能保證唯一性(即使 7 字節 UID 或任何大小的 UID 也不應該用於唯一性和安全性,因為它們太容易了)偽造))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM