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