Java读写NFC标签Ntag2x芯片源码
生活随笔
收集整理的這篇文章主要介紹了
Java读写NFC标签Ntag2x芯片源码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
發卡器介紹:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.11.14c4789euYabVr&id=615391857885
import com.sun.jna.Library ; import com.sun.jna.Native; import java.io.IOException;interface CLibrary extends Library {//DLL絕對路徑的地址獲取,注意要去空格,不要使用中文目錄//不同版本的讀寫器,接口DLL文件名稱、函數名稱是一樣的,但內核代碼不一樣,請選用與讀寫器、操作系統一致的OUR_MIFARE.dllString filePath = CLibrary.class.getResource("").getPath().replaceFirst("/","").replaceAll("%20"," ")+"OUR_MIFARE";CLibrary sdtapi = (CLibrary) Native.loadLibrary(filePath, CLibrary.class);//動態鏈接庫中的方法byte pcdbeep(int xms); //讓設備發出聲音byte pcdgetdevicenumber(byte[] devicenumber); //讀取設備編號byte piccrequest_ul(byte[] mypiccserial); //讀卡的序列號byte piccread_ul(byte ReadPageBegin,byte[] mypiccdata);//讀卡內4個頁數據byte piccwrite_ul(byte WritePage,byte[] mypiccdata); //寫數據到指定頁byte piccauthkey_ntag(byte[] mypicckey,byte[] mypiccntagpack); //校驗卡片密碼byte piccreadex_ntag(byte myctrlword,byte[] mypiccserial,byte[] mypicckey,byte myblockaddr,byte myblocksize,byte[] mypiccdata); //輕松讀卡,一次最多可讀12頁共48個字節的數據byte piccwriteex_ntag(byte myctrlword,byte[] mypiccserial,byte[] mypicckey,byte myblockaddr,byte myblocksize,byte[] mypiccdata); //輕松寫卡,一次最多可讀11頁共44個字節的數據byte piccinit_ntag(byte myctrlword,byte[] mypiccserial,byte[] mypicckey,byte[] mypiccdata); //設置卡密碼及保護機制 }public class RWNtag21x {public static void main(String[] args) throws Exception {System.setProperty("jna.encoding", "GBK");String filePath = CLibrary.class.getResource("").getPath().replaceFirst("/", "").replaceAll("%20", " ") + "OUR_MIFARE.DLL";System.out.println("本示例引用的DLL文件:" + filePath);if (args.length == 0) {System.out.println("\n請先輸入運行參數!");System.out.println("\n參數 0:驅動讀卡器嘀一聲");System.out.println("\n參數 1:讀取設備編號");System.out.println("\n參數 2:讀卡的序列號");System.out.println("\n參數 3:讀卡內4個連續頁的數據");System.out.println("\n參數 4:寫數據到指定頁");System.out.println("\n參數 5:校驗卡片密碼");System.out.println("\n參數 6:輕松讀卡,一次最多可讀12頁共48個字節的數據");System.out.println("\n參數 7:輕松寫卡,一次最多可讀11頁共44個字節的數據");System.out.println("\n參數 8:設置卡密碼及保護機制");return;}//Java中只能使用string1.equals(string2)的方式來比較字符串if (args[0].equals("0")) { //驅動讀卡器發嘀一聲System.out.print("\n0-驅動讀卡器嘀一聲\n");CLibrary.sdtapi.pcdbeep(50);System.out.print("結果:如果能聽到讀卡器嘀一聲表示成功,否則請檢查讀卡器是否已連上線!\n");} else if (args[0].equals("1")){ //讀取設備編號,可做為軟件加密狗用,也可以根據此編號在公司網站上查詢保修期限int status; //存放返回值byte[] devicenumber = new byte[4]; //4字節設備編號status = (int) (CLibrary.sdtapi.pcdgetdevicenumber(devicenumber) & 0xff);//& 0xff用于轉為無符號行數據System.out.print("\n1-讀取設備編號\n");System.out.print("結果:");if (status == 0) {CLibrary.sdtapi.pcdbeep(38);System.out.print("讀取成功!設備編號為:" + (devicenumber[0] & 0xff) + "-" + (devicenumber[1] & 0xff) + "-" + (devicenumber[2] & 0xff) + "-" + (devicenumber[3] & 0xff) + "\n");} else {PrintErrInf(status); //返回代碼提示}}else if (args[0].equals("2")){ //讀卡的序列號int status; //存放返回值byte[] mypiccserial = new byte[7]; //7字節卡號status = (int) (CLibrary.sdtapi.piccrequest_ul(mypiccserial) & 0xff);//& 0xff用于轉為無符號行數據System.out.print("\n2-讀卡的序列號\n");if (status == 0) {CLibrary.sdtapi.pcdbeep(38);String uidstr = "";for (int i = 0; i < 7; i++) {String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("7字節卡序號:" + uidstr+"\n");} else {PrintErrInf(status); //返回代碼提示}}else if (args[0].equals("3")){ //讀卡內4個頁的數據int status; //存放返回值byte[] mypiccserial = new byte[7]; //7字節卡號byte[] mypiccdata=new byte[16]; //16個字節讀卡的數據緩沖byte ReadPageBegin=4; //讀起始頁地址status = (int) (CLibrary.sdtapi.piccrequest_ul(mypiccserial) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {String uidstr = "";for (int i = 0; i < 7; i++) {String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("\n3-讀卡內4個頁的數據");System.out.print("\n卡序號:" + uidstr);status = (int) (CLibrary.sdtapi.piccread_ul(ReadPageBegin,mypiccdata) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {CLibrary.sdtapi.pcdbeep(38);String databuf = "";for (int i = 0; i < mypiccdata.length ; i++) {String bytestr = "00" + Integer.toHexString(mypiccdata[i] & 0xff);databuf = databuf + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("\n頁內數據:" + databuf + "\n");}else {PrintErrInf(status); //返回代碼提示}} else {PrintErrInf(status); //返回代碼提示}}else if (args[0].equals("4")){ //寫數據到指定頁int status; //存放返回值byte[] mypiccserial = new byte[7]; //7字節卡號byte[] mypiccdata=new byte[4]; //4個字節的數據緩沖byte WritePage=4; //頁地址status = (int) (CLibrary.sdtapi.piccrequest_ul(mypiccserial) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {String uidstr = "";for (int i = 0; i < 7; i++) {String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("\n4-寫數據到指定頁");System.out.print("\n卡序號:" + uidstr+"\n");mypiccdata[0]=0;mypiccdata[1]=1;mypiccdata[2]=2;mypiccdata[3]=3;status = (int) (CLibrary.sdtapi.piccwrite_ul(WritePage,mypiccdata) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {CLibrary.sdtapi.pcdbeep(38);System.out.print("第"+Integer.toString(WritePage)+"頁數據改寫成功!\n");}else {PrintErrInf(status); //返回代碼提示}} else {PrintErrInf(status); //返回代碼提示}}else if (args[0].equals("5")){ //校驗卡片密碼int status; //存放返回值byte[] mypiccserial = new byte[7]; //7字節卡號byte[] mypicckey=new byte[4]; //4個字節的卡密碼byte[] mypiccntagpack=new byte[2]; //返回的確認碼status = (int) (CLibrary.sdtapi.piccrequest_ul(mypiccserial) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {String uidstr = "";for (int i = 0; i < 7; i++) {String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("\n5-校驗卡片密碼");System.out.print("\n卡序號:" + uidstr+"\n");status = (int) (CLibrary.sdtapi.piccauthkey_ntag(mypicckey,mypiccntagpack) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {CLibrary.sdtapi.pcdbeep(38);System.out.print("卡密碼認證成功!確認碼為:"+Integer.toHexString(mypiccntagpack[0])+" "+Integer.toHexString(mypiccntagpack[1]));}else {PrintErrInf(status); //返回代碼提示}} else {PrintErrInf(status); //返回代碼提示}}else if (args[0].equals("6")){ //校輕松讀卡,一次最多可讀12頁共48個字節的數據int status; //存放返回值byte[] mypiccserial = new byte[7]; //7字節卡號byte[] mypicckey=new byte[4]; //4個字節的卡密碼byte[] mypiccdata=new byte[48]; //48個字節讀卡的數據緩沖byte myblockaddr=4; //讀起始頁地址byte myblocksize=12; //讀卡頁數byte myctrlword=0; //取值0不認證密碼,16要認證卡密碼if(myctrlword==16) { //如果要認證卡密碼,設置認證密碼mypicckey[0]=(byte) 0x12;mypicckey[1]=(byte) 0x34;mypicckey[2]=(byte) 0x56;mypicckey[3]=(byte) 0x78;}System.out.print("\n6-輕松讀卡");status = (int) (CLibrary.sdtapi.piccreadex_ntag(myctrlword,mypiccserial,mypicckey,myblockaddr,myblocksize,mypiccdata) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {CLibrary.sdtapi.pcdbeep(38);String uidstr = "";for (int i = 0; i < 7; i++) {String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("\n卡序號:" + uidstr);String databuf="";for (int i = 0; i < myblocksize*4; i++) {String bytestr = "00" + Integer.toHexString(mypiccdata[i] & 0xff);databuf = databuf + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("\n卡內數據:" + databuf+"\n");} else {PrintErrInf(status); //返回代碼提示}}else if (args[0].equals("7")) { //輕松寫卡,一次最多可讀11頁共44個字節的數據int status; //存放返回值byte[] mypiccserial = new byte[7]; //7字節卡號byte[] mypicckey = new byte[4]; //4個字節的卡密碼byte[] mypiccdata = new byte[44]; //44個字節寫卡緩沖byte myblockaddr = 4; //寫起始頁地址byte myblocksize = 11; //寫卡頁數byte myctrlword = 0; //取值0不認證密碼,16要認證卡密碼if (myctrlword == 16) { //如果要認證卡密碼,設置認證密碼mypicckey[0] = (byte) 0x12;mypicckey[1] = (byte) 0x34;mypicckey[2] = (byte) 0x56;mypicckey[3] = (byte) 0x78;}//寫中文或字母數字等字符信息,將要寫入的字符轉ASCII碼寫入String WriteStr = "偉大的中華人民共和國萬歲!1949-10-01 "; //將要寫入的文字生成字節數組byte[] WriteBuf = WriteStr.getBytes("gb2312");for (int i = 0; i < myblocksize*4; i++) { //指定寫卡數據,寫卡頁數*4個字節mypiccdata[i] = WriteBuf[i];}System.out.print("\n7-輕松寫卡");status = (int) (CLibrary.sdtapi.piccwriteex_ntag(myctrlword, mypiccserial, mypicckey, myblockaddr, myblocksize, mypiccdata) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {CLibrary.sdtapi.pcdbeep(38);String uidstr = "";for (int i = 0; i < 7; i++) {String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("\n卡序號:" + uidstr + ",寫卡成功!\n");} else {PrintErrInf(status); //返回代碼提示}}else if (args[0].equals("8")) { //設置卡密碼及保護機制int status; //存放返回值byte[] mypicckey = new byte[4]; //4個字節的卡舊密碼byte[] newPickey = new byte[44]; //4個字節的新密碼byte[] mypiccserial = new byte[7]; //7字節卡號byte EnOrDisKey = 1; //0開啟密碼保護功能,1取消密碼保護功能byte ReadNeedKey = 0; //取值0讀卡不需要認證密碼,非0讀卡也要認證密碼byte myctrlword = 16; //取值0不需要認證密碼,16要認證卡密碼 對卡操作byte KeyErrNum=0; //對卡操作允許密碼錯誤次數(0為不限次)byte[] mypiccdata=new byte[16]; //本次對卡的配置信息if (myctrlword == 16) { //如果要認證卡密碼,設置認證密碼mypicckey[0] = (byte) 0x12;mypicckey[1] = (byte) 0x34;mypicckey[2] = (byte) 0x56;mypicckey[3] = (byte) 0x78;}if(EnOrDisKey==0){ //卡片開啟密碼保護功能,開啟后要記住卡密碼,否則卡報廢!!!myctrlword=(byte)(myctrlword+4);mypiccdata[3]=20; //配置:密碼保護起始頁,要根據不同類型的卡來設置myctrlword=(byte)(myctrlword+1);mypiccdata[4]=(byte)(KeyErrNum % 8); //配置:最大卡密碼認證錯誤次數if(ReadNeedKey>0){ //配置:讀卡時需要認證卡密碼mypiccdata[4]=(byte)(mypiccdata[4]+(byte)(0x80));}myctrlword=(byte)(myctrlword+2); //配置:啟用計數器newPickey[0]=(byte) 0x12;newPickey[1]=(byte) 0x34;newPickey[2]=(byte) 0x56;newPickey[3]=(byte) 0x78; //配置:4個字節的新密碼mypiccdata[12]=(byte)(0x16);mypiccdata[13]=(byte)(0x16);}else{ //卡片取消密碼保護功能mypiccdata[3]=(byte)(0xff);myctrlword=(byte)(myctrlword+1);myctrlword=(byte)(myctrlword+2);}System.out.print("\n8-設置卡密碼及保護機制");status = (int) (CLibrary.sdtapi.piccinit_ntag(myctrlword,mypiccserial,mypicckey,mypiccdata) & 0xff);//& 0xff用于轉為無符號行數據if (status == 0) {CLibrary.sdtapi.pcdbeep(38);String uidstr = "";for (int i = 0; i < 7; i++) {String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);uidstr = uidstr + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";}System.out.print("\n卡序號:" + uidstr + ",設置卡密碼及保護機制成功!\n");} else {PrintErrInf(status); //返回代碼提示}}}//----------------------------------------------------------------------------------返回代碼提示static void PrintErrInf(int errcode) {switch(errcode){case 1:System.out.print("錯誤代碼:1,0~2塊都沒讀出來,可能刷卡太塊。但卡序列號已被讀出來!");break;case 2:System.out.print("錯誤代碼:2,第0塊已被讀出,但1~2塊讀取失敗。卡序列號已被讀出來!");break;case 3:System.out.print("錯誤代碼:3,第0、1塊已被讀出,但2塊讀取失敗。卡序列號已被讀出來!");break;case 8:System.out.print("錯誤代碼:8,未尋到卡,請重新拿開卡后再放到感應區!");break;case 9:System.out.print("錯誤代碼:9,有多張卡在感應區,尋卡過程中防沖突失敗,讀序列嗎錯誤!");break;case 10:System.out.print("錯誤代碼:10,該卡可能已被休眠,無法選中卡片!");break;case 11:System.out.print("錯誤代碼:11,密碼裝載失敗!");break;case 12:System.out.print("錯誤代碼:12,卡片密碼認證失敗!");break;case 13:System.out.print("錯誤代碼:13,讀本塊失敗,原因是刷卡太快或本塊所對應的區還沒通過密碼認證!");break;case 14:System.out.print("錯誤代碼:14,寫本塊失敗,原因是刷卡太快或本塊所對應的區還沒通過密碼認證!");break;case 21:System.out.print("錯誤代碼:21,沒有動態庫!");break;case 22:System.out.print("錯誤代碼:22,動態庫或驅動程序異常!");break;case 23:System.out.print("錯誤代碼:23,驅動程序錯誤或尚未安裝!");break;case 24:System.out.print("錯誤代碼:24,操作超時,一般是動態庫沒有反映!");break;case 25:System.out.print("錯誤代碼:25,發送字數不夠!");break;case 26:System.out.print("錯誤代碼:26,發送的CRC錯!");break;case 27:System.out.print("錯誤代碼:27,接收的字數不夠!");break;case 28:System.out.print("錯誤代碼:28,接收的CRC錯!");break;default:System.out.print("未知錯誤,錯誤代碼:"+Integer.toString(errcode));break;}} }總結
以上是生活随笔為你收集整理的Java读写NFC标签Ntag2x芯片源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx 二进制包安装mysql_二进
- 下一篇: Tcpdump 详解