赞
踩
T5557卡是美国Atmel公司生产的多功能非接触式射频卡芯片,属于125KHz的低频卡,在国内有广大的应用市场。该芯片共有330bit(比特)的EPROM(分布为10个区块, 每个区块33bit)。0页的块0是被保留用于设置T5557操作模式的参数配置块。第0页第7块可以作用户数据块使用,也可以作为保护全部数据的密码(假如在配置块中启用密码功能的话),防止非法改写数据。 第1页的1、2块保存了出厂商信息及唯一出厂ID,只能读取不可更改,T5567、T5577是T5557的升级版。
本示例使用的发卡器:T5557 T5567 T5577低频RFID读写器 EM4100 HID卡复制器 酒店门卡-淘宝网 (taobao.com)
- import com.sun.jna.Library ;
- import com.sun.jna.Native;
- import com.sun.jna.WString;
-
- interface CLibrary extends Library {
- //DLL绝对路径的地址获取,注意要去空格
- String filePath = CLibrary.class.getResource("").getPath().replaceFirst("/","").replaceAll("%20"," ")+"OUR_IDR";
- CLibrary sdtapi = (CLibrary) Native.loadLibrary(filePath, CLibrary.class);
-
- //动态链接库中的方法
- byte idr_beep(int xms); //让设备发出声音
- byte pcdgetdevicenumber(byte[] devicenumber); //读取设备编号
- String pcdgetdevicenumber_str(); //读取设备编号,输出字符串
- byte idr_read(byte[] mypiccserial ); //轻松读ID卡,只要卡在感应区,每次执行此方法都可以读到卡号
- byte hid_read(byte[] mypiccserial ); //轻松读ID卡,只要卡在感应区,每次执行此方法都可以读到卡号
- String idr_read_8h10d_str(); //读ID卡,输出十位十进制卡号
- byte t5557_read(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] blockflag,byte[] blockdata); //读t5557卡,
- byte t5557_write(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] blockflag,byte[] blockdata); //写t5557卡,
- byte t5557_init(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] configdata,byte[] newkey); //写t5557卡配置值
- byte t5557_changekey(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] newkey); //修改t5557卡密钥
- }
- public class IDReader {
- public static final byte NEEDSERIAL=1; //只对指定UID列号的卡操作
- public static final byte NEEDKEY=2; //需要用密码认证卡
- public static final byte LOCKBIT=4; //锁定配置块或数据块,仅对 t5557_init,t5557_write ,t5557_changekey函数有效
- public static final byte KEYENABLE=8; //启用本卡的密码功能
- public static final byte RESETCARD=16; //操作成功后重启卡片
-
- public static void main(String[] args) {
- System.setProperty("jna.encoding", "GBK");
- String filePath = CLibrary.class.getResource("").getPath().replaceFirst("/", "").replaceAll("%20", " ") + "OUR_IDR.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:轻松读ID卡");
- System.out.println("\n参数 4:轻松读HID卡");
- System.out.println("\n参数 5:轻松读ID卡,输出十位十进制卡号");
- System.out.println("\n参数 6:读T5557卡");
- System.out.println("\n参数 7:写T5557卡");
- System.out.println("\n参数 8:写T5557卡配置值");
- System.out.println("\n参数 9:修改T5557卡密钥");
- return;
- }
-
- //Java中只能使用string1.equals(string2)的方式来比较字符串
- if (args[0].equals("0")) { //驱动读卡器发嘀一声
- System.out.print("\n0-驱动读卡器嘀一声\n");
- CLibrary.sdtapi.idr_beep(50);
- System.out.print("结果:如果能听到读卡器嘀一声表示成功,否则请检查读卡器是否已连上线!\n\n");
-
- } else if (args[0].equals("1")) //读取设备编号,可做为软件加密狗用,也可以根据此编号在公司网站上查询保修期限
- {
- int status; //存放返回值
- byte[] devicenumber = new byte[4]; //4字节设备编号
-
- System.out.print("\n1-读取设备编号\n");
- status = (int) (CLibrary.sdtapi.pcdgetdevicenumber(devicenumber) & 0xff);//& 0xff用于转为无符号行数据
- System.out.print("结果:");
- if (status == 0) {
- CLibrary.sdtapi.idr_beep(38);
- System.out.print("读取成功!设备编号为:" + (devicenumber[0] & 0xff) + "-" + (devicenumber[1] & 0xff) + "-" + (devicenumber[2] & 0xff) + "-" + (devicenumber[3] & 0xff));
- } else {
- PrintErrInf(status); //错误代码提示
- }
-
- }else if (args[0].equals("2")) //读取设备编号,直接输出字符串
- {
- System.out.print("\n2-读取设备编号\n");
- String statustr = CLibrary.sdtapi.pcdgetdevicenumber_str().trim(); //设备编号
- if(statustr.length()==10) {
- CLibrary.sdtapi.idr_beep(38);
- System.out.print("读取成功!设备编号为:" + statustr + "\n");
- }else{
- PrintErrStr(statustr); //错误字符串代码提示
- }
-
- }else if (args[0].equals("3")) //轻松读ID卡
- {
- int status; //存放返回值
- byte[] mypiccserial = new byte[5]; //5字节卡序列号
-
- System.out.print("\n3-轻松读卡\n");
- status = (int) (CLibrary.sdtapi.idr_read(mypiccserial ) & 0xff); //只要卡在感应区,每次执行此方法都可以读到卡号
- System.out.print("结果:");
- if (status == 0) {
- CLibrary.sdtapi.idr_beep(38);
- String serialnumber = "";
- for (int i = 0; i < 5; i++) {
- String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
- serialnumber = serialnumber + bytestr.substring(bytestr.length() - 2, bytestr.length());
- }
- System.out.print("读取成功!16进制卡序列号为:" + serialnumber+"\n");
-
- long cardnum;
- cardnum=mypiccserial[4] & 0xff;
- cardnum=cardnum+(mypiccserial[3] & 0xff) *256;
- cardnum=cardnum+(mypiccserial[2] & 0xff) *65536;
- cardnum=cardnum+(mypiccserial[1] & 0xff) *16777216;
- long cardno10 = 0;
- for (int j=28; j>=0; j-=4) {
- cardno10 = cardno10<<4 | (cardnum>>>j & 0xF);
- }
- System.out.print("换算成10进制卡号:"+String.format("%010d", cardno10)+"\n");
- } else {
- PrintErrInf(status); //错误代码提示
- }
-
- }else if (args[0].equals("4")) //轻松读HID卡
- {
- int status; //存放返回值
- byte[] mypiccserial = new byte[7]; //7字节卡序列号
-
- System.out.print("\n4-轻松读HID卡\n");
- status = (int) (CLibrary.sdtapi.hid_read(mypiccserial ) & 0xff);
- System.out.print("结果:");
- if (status == 0) {
- CLibrary.sdtapi.idr_beep(38);
- String serialnumber = "";
- for (int i = 0; i < 7; i++) {
- String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
- serialnumber = serialnumber + bytestr.substring(bytestr.length() - 2, bytestr.length());
- }
- System.out.print("读取成功!16进制卡序列号为:" + serialnumber+"\n");
-
- long cardnum;
- cardnum=mypiccserial[6] & 0xff;
- cardnum=cardnum+(mypiccserial[5] & 0xff) *256;
- cardnum=cardnum+(mypiccserial[4] & 0xff) *65536;
- cardnum=cardnum+(mypiccserial[3] & 0xff) *16777216;
- long cardno10 = 0;
- for (int j=28; j>=0; j-=4) {
- cardno10 = cardno10<<4 | (cardnum>>>j & 0xF);
- }
- System.out.print("换算成8H10D卡号:"+String.format("%010d", cardno10)+"\n");
- } else {
- PrintErrInf(status); //错误代码提示
- }
-
- }else if (args[0].equals("5")) //读ID卡,输出十位十进制卡号
- {
- System.out.print("\n5-读10进制ID卡号\n");
- String statustr = CLibrary.sdtapi.idr_read_8h10d_str().trim(); //只要卡在感应区,每次执行此方法都可以读到卡号
- if(statustr.length()==10) {
- CLibrary.sdtapi.idr_beep(38);
- System.out.print("读卡成功!8H10D卡号为:" + statustr + "\n");
- }else{
- PrintErrStr(statustr); //错误字符串代码提示
- }
-
- }else if (args[0].equals("6")) //读T5557卡
- {
- System.out.print("\n6-读t5557卡\n");
- byte status; //存放返回值
- byte myctrlword=0; //控制字
- byte[] oldpicckey=new byte[4]; //认证密钥
- byte[] mypiccserial=new byte[6]; //卡UID序列号
- byte[] mypiccdata=new byte[100]; //读卡数据缓冲:卡无线转输分频比、卡内容长度(字节数),及最多返回12个块的数据
- byte[] mypiccblockflag=new byte[2]; //指定本次操作的块
- boolean withkey=false; //是否要认证卡密钥
- boolean thiscarduit =false; //是否只操作指定UID序号的卡
-
- if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
- myctrlword=(byte)(myctrlword+NEEDKEY);
- String Keyhexstr="12345678"; //认证密钥
- for(int i=0;i<4;i++){
- oldpicckey[i]=(byte)Integer.parseInt(Keyhexstr.substring(i*2,(i+1)*2),16);
- }
- }
- if(thiscarduit){ //本次只操作指定UID号的卡,mypiccserial
- myctrlword=(byte)(myctrlword+NEEDSERIAL);
- String Uidhexstr="000000000000"; //卡片uid
- for(int i=0;i<6;i++){
- mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
- }
- }
-
- String Seleblockstr0="11111111"; //第0页每块选取状态,从左到右依次表示第7、6、5、4、3、2、1、0块是否要操作,取1表示该块要读,取0表示该块不读,如要读0、1、3 块取值为 00001011,读第0页全部块为 11111111
- String Seleblockstr1="11110"; //第1页每块选取状态,从左到右依次表示第3、2、1、0块是否要操作,取1表示该块要读,取0表示该块不读,该页总计4块,最右边表示页选取值0
- mypiccblockflag[0]=(byte)Integer.parseInt(Seleblockstr0,2);
- mypiccblockflag[1]=(byte)Integer.parseInt(Seleblockstr1,2);
-
- status = CLibrary.sdtapi.t5557_read(myctrlword,mypiccserial,oldpicckey,mypiccblockflag,mypiccdata);
- if(status == 0) {
- CLibrary.sdtapi.idr_beep(38);
- String cardnohex="";
- for (int i=0;i<6;i++){
- String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
- cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
- }
- System.out.print("读卡成功,16进制卡序列号:"+cardnohex+"\n");
- System.out.print("卡无线转输分频比:"+Integer.toString(mypiccdata[0])+"\n");
- if(mypiccdata[1]>0) {
- String blockdata = "块内数据:";
- for (int i = 0; i < mypiccdata[1]; i++) {
- String bytestr = "00" + Integer.toHexString(mypiccdata[2 + i] & 0xff);
- blockdata = blockdata + bytestr.substring(bytestr.length() - 2, bytestr.length()) + " ";
- }
- System.out.print(blockdata+"\n");
- }
- }else {
- PrintErrInf(status); //错误代码提示
- }
-
- }else if (args[0].equals("7")) //写T5557卡
- {
- System.out.print("\n7-写t5557卡块\n");
- byte status; //存放返回值
- byte myctrlword=0; //控制字
- byte[] oldpicckey=new byte[4]; //认证密钥
- byte[] mypiccserial=new byte[6]; //卡UID序列号
- byte[] mypiccdata=new byte[50]; //读卡数据缓冲:卡无线转输分频比、卡内容长度(字节数),及最多返回12个块的数据
- byte[] mypiccblockflag=new byte[2]; //指定本次操作的块
- boolean withkey=false; //是否要认证卡密钥
- boolean thiscarduit =false; //是否只操作指定UID序号的卡
-
- if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
- myctrlword=(byte)(myctrlword+NEEDKEY);
- String Keyhexstr="12345678"; //认证密钥
- for(int i=0;i<4;i++){
- oldpicckey[i]=(byte)Integer.parseInt(Keyhexstr.substring(i*2,(i+1)*2),16);
- }
- }
- if(thiscarduit){ //本次只操作指定UID号的卡,mypiccserial
- myctrlword=(byte)(myctrlword+NEEDSERIAL);
- String Uidhexstr="000000000000"; //卡片uid
- for(int i=0;i<6;i++){
- mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
- }
- }
-
- String Seleblockstr0="11111110"; //第0页每块选取状态,从左到右依次表示第7、6、5、4、3、2、1、0块是否要操作,取1表示该块要写,取0表示该块不写,如要写1、3 块取值为 00001010,第0块是配置块不能用此功能写入,如开启了密码功能,第7块为密码块也不能用此功能写
- String Seleblockstr1="00000"; //第1页每块选取状态,此页只读不可写,
- mypiccblockflag[0]=(byte)Integer.parseInt(Seleblockstr0,2);
- mypiccblockflag[1]=(byte)Integer.parseInt(Seleblockstr1,2);
-
- String writedatahex="11111111222222223333333344444444555555556666666677777777"; //写入的数据,实际写入数据的块 由mypiccblockflag值决定
- for (int i=0;i<28;i++){
- mypiccdata[i]=(byte)Integer.parseInt(writedatahex.substring(i*2,(i+1)*2),16);
- }
- status = CLibrary.sdtapi.t5557_write(myctrlword,mypiccserial,oldpicckey,mypiccblockflag,mypiccdata);
- if(status == 0) {
- CLibrary.sdtapi.idr_beep(38);
- String cardnohex = "";
- for (int i = 0; i < 6; i++) {
- String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
- cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length());
- }
- System.out.print("写卡成功,16进制卡序列号:" + cardnohex + "\n");
- }else {
- PrintErrInf(status); //错误代码提示
- }
-
- }else if (args[0].equals("8")) //写T5557卡配置块
- {
- System.out.print("\n8-写t5557卡配置块\n");
- byte status; //存放返回值
- byte myctrlword=0; //控制字
- byte[] oldpicckey=new byte[4]; //认证密钥
- byte[] newpicckey=new byte[4]; //卡片新密钥
- byte[] mypiccserial=new byte[6]; //卡UID序列号
- byte[] configdata=new byte[4]; //配置值
- boolean withkey=false; //是否要认证卡密钥
- boolean newkeyEn=false; //是否要开启卡片密钥功能
-
- if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
- myctrlword=(byte)(myctrlword+NEEDKEY);
- String oldKeyhexstr="12345678"; //认证密钥
- for(int i=0;i<4;i++){
- oldpicckey[i]=(byte)Integer.parseInt(oldKeyhexstr.substring(i*2,(i+1)*2),16);
- }
- }
-
- String configdatahex="00088028"; //卡片出厂默认配置值,不同功能配置值不一样,请查询相关资料
- if (newkeyEn){ //卡片启用密钥保护功能
- myctrlword=(byte)(myctrlword+KEYENABLE);
- configdatahex="00088038"; //开启密钥配置值,不同功能配置值不一样,请查询相关资料
- String newKeyhexstr="12345678"; //新密钥
- for(int i=0;i<4;i++){
- newpicckey[i]=(byte)Integer.parseInt(newKeyhexstr.substring(i*2,(i+1)*2),16);
- }
- }
-
- for (int i=0;i<4;i++){
- configdata[i]=(byte)Integer.parseInt(configdatahex.substring(i*2,(i+1)*2),16);
- }
-
- status = CLibrary.sdtapi.t5557_init(myctrlword,mypiccserial,oldpicckey,configdata,newpicckey);
- if(status == 0) {
- CLibrary.sdtapi.idr_beep(38);
- String cardnohex = "";
- for (int i = 0; i < 6; i++) {
- String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
- cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length());
- }
- System.out.print("写配置块成功,16进制卡序列号:" + cardnohex + "\n");
- }else {
- PrintErrInf(status); //错误代码提示
- }
-
- }else if (args[0].equals("9")) //修改T5557卡密钥
- {
- System.out.print("\n9-修改T5557卡密钥\n");
- byte status; //存放返回值
- byte myctrlword=0; //控制字
- byte[] oldpicckey=new byte[4]; //认证密钥
- byte[] newpicckey=new byte[4]; //卡片新密钥
- byte[] mypiccserial=new byte[6]; //卡UID序列号
- boolean withkey=true; //是否要认证卡密钥
- boolean thiscarduit =false; //是否只操作指定卡号的卡
-
- if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
- myctrlword=(byte)(myctrlword+NEEDKEY);
- String oldKeyhexstr="12345678"; //认证密钥
- for(int i=0;i<4;i++){
- oldpicckey[i]=(byte)Integer.parseInt(oldKeyhexstr.substring(i*2,(i+1)*2),16);
- }
- }
-
- if(thiscarduit){ //本次只操作指定UID号的卡,mypiccserial
- myctrlword=(byte)(myctrlword+NEEDSERIAL);
- String Uidhexstr="000000000000"; //卡片uid
- for(int i=0;i<6;i++){
- mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
- }
- }
-
- String newKeyhexstr="12345678"; //新密钥
- for(int i=0;i<4;i++){
- newpicckey[i]=(byte)Integer.parseInt(newKeyhexstr.substring(i*2,(i+1)*2),16);
- }
-
- status = CLibrary.sdtapi.t5557_changekey(myctrlword,mypiccserial,oldpicckey,newpicckey);
- if(status == 0) {
- CLibrary.sdtapi.idr_beep(38);
- String cardnohex = "";
- for (int i = 0; i < 6; i++) {
- String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
- cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length());
- }
- System.out.print("修改卡密钥成功,16进制卡序列号:" + cardnohex + "\n");
- }else {
- PrintErrInf(status); //错误代码提示
- }
- }
-
-
- }
-
- //----------------------------------------------------------------------------------错误字符串代码提示
- static void PrintErrStr(String Errstr){
- if(Errstr.equals("ER08")){
- System.out.print("错误代码:ER08,未寻到卡,请重新拿开卡后再放到感应区!\n");
- } else if(Errstr.equals("ER22")){
- System.out.print("错误代码:ER22,动态库或驱动程序异常!\n");
- } else if(Errstr.equals("ER23")){
- System.out.print("错误代码:ER23,驱动程序错误或尚未安装!\n");
- } else if(Errstr.equals("ER24")){
- System.out.print("错误代码:ER24,操作超时,一般是动态库没有反映!\n");
- }else {
- System.out.print("错误代码:"+Errstr);
- }
- }
-
- //----------------------------------------------------------------------------------错误代码提示
- static void PrintErrInf(int errcode) {
- switch(errcode){
- case 1:
- System.out.print("错误代码:1,写入配置的值不正确,请重新写入!\n");
- break;
- case 2:
- System.out.print("错误代码:2,本卡尚未开启密码功能,函数myctrlword中无需加入NEEDKEY!\n");
- break;
- case 3:
- System.out.print("错误代码:3,需要密码才能读卡,函数myctrlword要加入NEEDKEY!\n");
- break;
- case 5:
- System.out.print("错误代码:5,密码错误!\n");
- break;
- case 8:
- System.out.print("错误代码:8,未寻到卡,请重新拿开卡后再放到感应区!\n");
- break;
- case 21:
- System.out.print("错误代码:21,没有动态库!\n");
- break;
- case 22:
- System.out.print("错误代码:22,动态库或驱动程序异常!\n");
- break;
- case 23:
- System.out.print("错误代码:23,驱动程序错误或尚未安装!\n");
- break;
- case 24:
- System.out.print("错误代码:24,操作超时,一般是动态库没有反映!\n");
- break;
- case 25:
- System.out.print("错误代码:25,发送字数不够!\n");
- break;
- case 26:
- System.out.print("错误代码:26,发送的CRC错!\n");
- break;
- case 27:
- System.out.print("错误代码:27,接收的字数不够!\n");
- break;
- case 28:
- System.out.print("错误代码:28,接收的CRC错!\n");
- break;
- default:
- System.out.print("未知错误,错误代码:"+Integer.toString(errcode)+"\n");
- break;
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。