Saya telah mengumpulkan contoh kode berikut untuk mendeteksi kartu pintar Mifare menggunakan perpustakaan javax.smartcardio. Kode ini berfungsi baik untuk tipe Mifare yang terdaftar.
public class DetectCardTester {
private static final String PROTOCOL = "T=1";
static Map<String,String> KNOWN_CARD_TYPES = ImmutableMap.<String, String>builder()
.put("00-01", "Mifare 1K")
.put("00-02", "Mifare 4K")
.put("00-03", "Mifare Ultralight")
.put("00-26", "Mifare Mini")
.build();
public static void main(String... args) {
try {
final TerminalFactory terminalFactory = SmartcardTerminalFactory.create();
System.out.println("Place card on the reader");
final Card card = awaitCard(terminalFactory, 3, SECONDS);
final ATR atr = card.getATR();
final byte[] bytes = atr.getBytes();
System.out.println("ATR=" + String.valueOf(Hex.encodeHex(bytes, false)));
if (bytes != null && bytes.length > 13) {
String typeCode = String.format("%02X-%02X", bytes[13], bytes[14]);
if (KNOWN_CARD_TYPES.containsKey(typeCode)) {
System.out.println("Known Type:" + KNOWN_CARD_TYPES.get(typeCode));
} else {
System.out.println("Unknown Type:" + typeCode);
}
}
// TODO: Detect Desfire Card
} catch (Throwable t) {
t.printStackTrace();
}
}
public static Card awaitCard(final TerminalFactory terminalFactory, final int qty, final TemporalUnit unit) throws CardException {
LocalDateTime timeout = now().plus(qty, unit);
while (now().isBefore(timeout)) {
Optional<CardTerminal> cardTerminal = getCardPresentTerminal(terminalFactory);
if (cardTerminal.isPresent()) {
return cardTerminal.get().connect(PROTOCOL);
}
}
throw new CardNotPresentException("Timed out waiting for card");
}
private static Optional<CardTerminal> getCardPresentTerminal(final TerminalFactory terminalFactory) throws CardException {
List<CardTerminal> terminals = terminalFactory.terminals().list();
for (CardTerminal cardTerminal : terminals) {
if (cardTerminal.isCardPresent()) {
return Optional.of(cardTerminal);
}
}
for (CardTerminal cardTerminal : terminals) {
// waitForCardPresent / Absent doesn't work with some Jacax.smartcard.io implementations
// i.e. OSX http://bugs.java.com/view_bug.do?bug_id=7195480
// This is why we have the imediate check above
if (cardTerminal.waitForCardPresent(250)) {
return Optional.of(cardTerminal);
}
}
return Optional.empty();
}
}
Saya menggunakan sumber daya berikut untuk menyatukan kode ini:
- http://downloads.acs.com.hk/drivers/en/API-ACR122U-2.02.pdf
- Cara mendapatkan SAK untuk Mengidentifikasi jenis kartu pintar menggunakan JAWA?
Saya ingin menerapkan komentar TODO untuk mendeteksi kartu Desfire. Jika saya menempatkan kartu Desfire saat membaca kode ini, outputnya hanya seperti ini:
Place card on the reader
ATR=3B8180018080
Saya menemukan pertanyaan ini Tentukan jenis kartu dari ATR yang sedikit membantu tetapi saya melewatkan sesuatu . HistoricalByte untuk kartu yang dimaksud adalah 0x80 dan saya tidak dapat menemukan informasi apa pun.
Jika memungkinkan saya akan sangat menghargai contoh kode di atas yang diperluas sehingga dapat mendeteksi jenis kartu Desfire.