EM4305/EM4205卡是采用瑞士EM微电子公司工作频率为125kHz,具有读、写功能的非接触式RFID射频芯片,它具有功耗低、可提供多种数据传输速率和数据编码方法等特点,适合射频芯片ISO 11784/11785规范,该芯片被广泛应用于动物识别和跟踪、智能门锁、通道门禁等一卡通管理系统。
EM4305/EM4205卡的EEPROM储存空间为512位,分为16个块,每个块32位,块1为UID块,块2为密码块,块4为配置块,块14、15为锁定标志块。可在-40℃~85℃在温度下工作。
EM4305/EM4205卡可以修改其配置信息将其模拟成兼容EM4100的ID卡,可用于ID卡的复制,其内部存储结构如下图:
本示例使用的发卡器: EM4305 EM4469 ISO11784/85低频FXD-B动物标签AGV地标读写发卡器-淘宝网 (taobao.com)
import com.reader.ouridr;
public class Main {
public static final byte NEEDSERIAL=1; //只对指定UID列号的卡操作
public static final byte NEEDKEY=2; //需要用密码认证卡
public static void main(String[] args) {
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:轻松读4100_ID卡");
System.out.println("\n参数 4:轻松读4100_ID卡,卡在感应区时只能读一次,需将卡从感应区盒开再放入感应区才能再次读到卡");
System.out.println("\n参数 5:轻松读4100_ID卡,输出十位十进制卡号");
System.out.println("\n参数 6:轻松读4100_ID卡,输出十位十进制卡号,卡在感应区时只能读一次");
System.out.println("\n参数 7:写EM4205、4305卡配置值");
System.out.println("\n参数 8:写EM4469、4569卡配置值");
System.out.println("\n参数 9:轻松读Em4205、4305、4469、4569卡");
System.out.println("\n参数 10:轻松写Em4205、4305、4469、4569卡");
System.out.println("\n参数 11:修改Em4205、4305、4469、4569卡密钥");
System.out.println("\n参数 12:锁定Em4205、4305、4469、4569块(谨慎使用!!!)");
System.out.println("\n参数 13:将Em4205、4305卡制成4100ID卡");
System.out.println("\n参数 14:轻松读HID卡");
return;
}
//Java中只能使用string1.equals(string2)的方式来比较字符串
if (args[0].equals("0")) { //驱动读卡器发嘀一声
System.out.print("\n0-驱动读卡器嘀一声\n");
ouridr.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) (idreadertest.pcdgetdevicenumber(devicenumber) & 0xff);//& 0xff用于转为无符号行数据
System.out.print("结果:");
if (status == 0) {
idreadertest.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 = idreadertest.pcdgetdevicenumber_str().trim(); //设备编号
if(statustr.length()==10) {
idreadertest.idr_beep(38);
System.out.print("读取成功!设备编号为:" + statustr + "\n");
}else{
PrintErrStr(statustr); //错误字符串代码提示
}
}
else if (args[0].equals("3")){ //轻松读卡4100ID卡
int status; //存放返回值
byte[] mypiccserial = new byte[5]; //5字节卡序列号
System.out.print("\n3-轻松读卡\n");
status = (int) (idreadertest.idr_read(mypiccserial ) & 0xff); //只要卡在感应区,每次执行此方法都可以读到卡号
System.out.print("结果:");
if (status == 0) {
idreadertest.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")){ //轻松读卡,卡在感应区时只能读一次,需将卡从感应区盒开再放入感应区才能再次读到卡
int status; //存放返回值
byte[] mypiccserial = new byte[5]; //5字节卡序列号
System.out.print("\n4-轻松读一次卡\n");
status = (int) (idreadertest.idr_read_once(mypiccserial ) & 0xff); //卡在感应区时只能读一次,需将卡从感应区盒开再放入感应区才能再次读到卡
System.out.print("结果:");
if (status == 0) {
idreadertest.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");
int 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("5")){ //读卡,输出十位十进制卡号
System.out.print("\n5-读10进制卡号\n");
String statustr = idreadertest.idr_read_8h10d_str().trim(); //只要卡在感应区,每次执行此方法都可以读到卡号
if(statustr.length()==10) {
idreadertest.idr_beep(38);
System.out.print("读卡成功!8H10D卡号为:" + statustr + "\n");
}else{
PrintErrStr(statustr); //错误字符串代码提示
}
}
else if (args[0].equals("6")){ //读卡,输出十位十进制卡号,卡在感应区时只能读一次,需将卡从感应区盒开再放入感应区才能再次读到卡
System.out.print("\n6-读10进制卡号,只读一次\n");
String statustr = idreadertest.idr_read_once_8h10d_str().trim(); 卡在感应区时只能读一次,需将卡从感应区盒开再放入感应区才能再次读到卡
if(statustr.length()==10) {
idreadertest.idr_beep(38);
System.out.print("读卡成功!8H10D卡号为:" + statustr + "\n");
}else{
PrintErrStr(statustr); //错误字符串代码提示
}
}
else if (args[0].equals("7")){ //写EM4205、4305配置块
System.out.print("\n7-写EM4205、4305卡配置值\n");
byte status; //存放返回值
byte myctrlword=0; //控制字
byte[] oldpicckey=new byte[4]; //认证密钥
byte[] mypiccserial=new byte[4]; //卡UID序列号
byte[] configdata=new byte[4]; //配置值
boolean withkey=false; //是否要认证卡密钥
boolean thiscarduit =false; //是否只操作指定UID序号的卡
if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
myctrlword=(byte)(myctrlword+NEEDKEY);
String oldKeyhexstr="00000000"; //认证密钥
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="00000000"; //卡片uid
for(int i=0;i<4;i++){
mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
}
}
//EM4205、4305卡常用配置值说明
//5F800100 数率RF/64、曼彻斯特码、 0-15块任意读.0-13块任意写,14-15块需密码写,卡片出厂默认配置值
//5F800500 数率RF/64、曼彻斯特码、 0-1块任意读,3-15块需密码读,0-13块任意写,14-15块需密码写
//5F801100 数率RF/64、曼彻斯特码、 0-15任意读,0-15块需密码写
//5F801500 数率RF/64、曼彻斯特码、 0-1块任意读,3-15块需密码读,0-15块需密码写
String configdatahex="5F800100"; //卡片出厂默认配置值,不同功能配置值不一样,请查询相关资料
for (int i=0;i<4;i++){
configdata[i]=(byte)Integer.parseInt(configdatahex.substring(i*2,(i+1)*2),16);
}
status = ouridr.em4305init(myctrlword,mypiccserial,oldpicckey,configdata);
if(status == 0) {
ouridr.beep(38);
String cardnohex = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
System.out.print("写EM4305卡配置块成功,16进制卡序列号:" + cardnohex + "\n");
}else {
PrintErrInf(status); //错误代码提示
}
}
else if (args[0].equals("8")){ //写EM4469、4569配置块
System.out.print("\n8-写EM4469、4569卡配置值\n");
byte status; //存放返回值
byte myctrlword=0; //控制字
byte[] oldpicckey=new byte[4]; //认证密钥
byte[] mypiccserial=new byte[4]; //卡UID序列号
byte[] configdata=new byte[4]; //配置值
boolean withkey=false; //是否要认证卡密钥
boolean thiscarduit =false; //是否只操作指定UID序号的卡
if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
myctrlword=(byte)(myctrlword+NEEDKEY);
String oldKeyhexstr="00000000"; //认证密钥
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="00000000"; //卡片uid
for(int i=0;i<4;i++){
mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
}
}
//EM4469、4569卡常用配置值说明
//45800100 数率RF/64、曼彻斯特码、 0-15块任意读.0-15块任意写,卡片出厂默认配置值
//45800500 数率RF/64、曼彻斯特码、 0-1块任意读,3-15块需密码读,0-15块任意写
//45801100 数率RF/64、曼彻斯特码、 0-15任意读,0-15块需密码写
//45801500 数率RF/64、曼彻斯特码、 0-1块任意读,3-15块需密码读,0-15块需密码写
String configdatahex="45800100"; //卡片出厂默认配置值,不同功能配置值不一样,请查询相关资料
for (int i=0;i<4;i++){
configdata[i]=(byte)Integer.parseInt(configdatahex.substring(i*2,(i+1)*2),16);
}
status = ouridr.em4469init(myctrlword,mypiccserial,oldpicckey,configdata);
if(status == 0) {
ouridr.beep(38);
String cardnohex = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
System.out.print("写EM4469卡配置块成功,16进制卡序列号:" + cardnohex + "\n");
}else {
PrintErrInf(status); //错误代码提示
}
}
else if (args[0].equals("9")){ //读Em4205、4305、4469、4569卡
System.out.print("\n9-读Em4205、4305、4469、4569卡\n");
byte status; //存放返回值
byte myctrlword=0; //控制字
byte[] oldpicckey=new byte[4]; //认证密钥
byte[] mypiccserial=new byte[4]; //卡UID序列号
byte[] mypiccdata=new byte[100]; //读卡数据缓冲:卡无线转输分频比、卡内容长度(字节数),及最多返回12个块的数据
byte[] mypiccblockflag=new byte[2]; //指定本次操作的块
boolean withkey=true; //是否要认证卡密钥
boolean thiscarduit =false; //是否只操作指定UID序号的卡
if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
myctrlword=(byte)(myctrlword+NEEDKEY);
String Keyhexstr="00000000"; //认证密钥
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="00000000"; //卡片uid
for(int i=0;i<4;i++){
mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
}
}
String Seleblockstr0="00111011"; //从左到右依次表示第7、6、5、4、3、2、1、0块是否要操作,取1表示该块要读,取0表示该块不读,如要读0、1、3 块取值为 00001011,
String Seleblockstr1="00000000"; //从左到右依次表示第15、14、13、12、11、10、9、8块是否要操作,取1表示该块要读,取0表示该块不读,如要读10、12、14 块取值为 01010100,
mypiccblockflag[0]=(byte)Integer.parseInt(Seleblockstr0,2);
mypiccblockflag[1]=(byte)Integer.parseInt(Seleblockstr1,2);
status = ouridr.em4305read(myctrlword,mypiccserial,oldpicckey,mypiccblockflag,mypiccdata);
if(status == 0) {
ouridr.beep(38);
String cardnohex="";
for (int i=0;i<4;i++){
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
System.out.print("读EM4305卡成功,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("10")){ //写Em4205、4305、4469、4569卡
System.out.print("\n10-写Em4205、4305、4469、4569卡\n");
byte status; //存放返回值
byte myctrlword=0; //控制字
byte[] oldpicckey=new byte[4]; //认证密钥
byte[] mypiccserial=new byte[4]; //卡UID序列号
byte[] mypiccdata=new byte[100]; //读卡数据缓冲:卡无线转输分频比、卡内容长度(字节数),及最多返回12个块的数据
byte[] mypiccblockflag=new byte[2]; //指定本次操作的块
boolean withkey=true; //是否要认证卡密钥
boolean thiscarduit =false; //是否只操作指定UID序号的卡
if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
myctrlword=(byte)(myctrlword+NEEDKEY);
String Keyhexstr="00000000"; //认证密钥
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="00000000"; //卡片uid
for(int i=0;i<4;i++){
mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
}
}
//写入的数据,实际写入数据的块由mypiccblockflag值决定,1块为UID已固化、2块为密钥块、4块为配置块、14、15为锁定标志块,都不能用此方式写
String writedatahex="00000000333333335555555566666666777777778888888899999999AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD";
for (int i=0;i<28;i++){
mypiccdata[i]=(byte)Integer.parseInt(writedatahex.substring(i*2,(i+1)*2),16);
}
String Seleblockstr0="00001000"; //从左到右依次表示第7、6、5、4、3、2、1、0块是否要操作,取1表示该块要写,取0表示该块不写,如要写3、5 块取值为 00101000,
String Seleblockstr1="00000000"; //从左到右依次表示第15、14、13、12、11、10、9、8块是否要操作,取1表示该块要写,取0表示该块不写,如要写8、9、10 块取值为 00000111,
mypiccblockflag[0]=(byte)Integer.parseInt(Seleblockstr0,2);
mypiccblockflag[1]=(byte)Integer.parseInt(Seleblockstr1,2);
status = ouridr.em4305write(myctrlword,mypiccserial,oldpicckey,mypiccblockflag,mypiccdata);
if(status == 0) {
ouridr.beep(38);
String cardnohex="";
for (int i=0;i<4;i++){
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
System.out.print("写EM4305卡成功,16进制卡序列号:"+cardnohex+"\n");
}else {
PrintErrInf(status); //错误代码提示
}
}
else if (args[0].equals("11")){ //修改Em4205、4305、4469、4569卡密钥
System.out.print("\n11-修改Em4205、4305、4469、4569卡密钥\n");
byte status; //存放返回值
byte myctrlword=0; //控制字
byte[] oldpicckey=new byte[4]; //认证密钥
byte[] newpicckey=new byte[4]; //卡片新密钥
byte[] mypiccserial=new byte[4]; //卡UID序列号
boolean withkey=true; //是否要认证卡密钥
boolean thiscarduit =false; //是否只操作指定卡号的卡
if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
myctrlword=(byte)(myctrlword+NEEDKEY);
String oldKeyhexstr="00000000"; //认证密钥
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="00000000"; //卡片uid
for(int i=0;i<4;i++){
mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
}
}
String newKeyhexstr="00000000"; //新密钥
for(int i=0;i<4;i++){
newpicckey[i]=(byte)Integer.parseInt(newKeyhexstr.substring(i*2,(i+1)*2),16);
}
status = ouridr.em4305changekey(myctrlword,mypiccserial,oldpicckey,newpicckey);
if(status == 0) {
ouridr.beep(38);
String cardnohex = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
System.out.print("修改EM4305卡密钥成功,16进制卡序列号:" + cardnohex + "\n");
}else {
PrintErrInf(status); //错误代码提示
}
}
else if (args[0].equals("12")){ //锁定Em4205、4305、4469、4569块
System.out.print("\n12-锁定Em4205、4305、4469、4569块\n");
byte status; //存放返回值
byte myctrlword=0; //控制字
byte[] oldpicckey=new byte[4]; //认证密钥
byte[] mypiccserial=new byte[4]; //卡UID序列号
byte[] mypiccblockflag=new byte[2]; //指定本次操作的块
boolean withkey=true; //是否要认证卡密钥
boolean thiscarduit =false; //是否只操作指定UID序号的卡
if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
myctrlword=(byte)(myctrlword+NEEDKEY);
String Keyhexstr="00000000"; //认证密钥
for(int i=0;i<4;i++){
oldpicckey[i]=(byte)Integer.parseInt(Keyhexstr.substring(i*2,(i+1)*2),16);
}
}else{
System.out.print("锁定块需要带密码操作!\n");
return;
}
if(thiscarduit){ //本次只操作指定UID号的卡,mypiccserial
myctrlword=(byte)(myctrlword+NEEDSERIAL);
String Uidhexstr="00000000"; //卡片uid
for(int i=0;i<4;i++){
mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
}
}
//块1为uid块,只能读取不需锁定!
//块2为配置区,只能在初始化函数中操作不需锁定
//14、15 块为锁定标志块,只能在初始化函数中操作不需锁定!
String Seleblockstr0="00001000"; //从左到右依次表示第7、6、5、4、3、2、1、0块是否要操作,取1表示该块要锁定,取0表示该块不锁,如要锁3、5 块取值为 00101000,
String Seleblockstr1="00000000"; //从左到右依次表示第15、14、13、12、11、10、9、8块是否要操作,取1表示该块要锁,取0表示该块不锁,如要锁8、9、10 块取值为 00000111,
mypiccblockflag[0]=(byte)Integer.parseInt(Seleblockstr0,2);
mypiccblockflag[1]=(byte)Integer.parseInt(Seleblockstr1,2);
status = ouridr.em4305lock(myctrlword,mypiccserial,oldpicckey,mypiccblockflag);
if(status == 0) {
ouridr.beep(38);
String cardnohex="";
for (int i=0;i<4;i++){
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length()) ;
}
System.out.print("锁定EM卡块成功,16进制卡序列号:"+cardnohex+"\n");
}else {
PrintErrInf(status); //错误代码提示
}
}
else if (args[0].equals("13")){ //将Em4205、4305卡制成4100ID卡
System.out.print("\n13-将Em4205、4305卡制成4100ID卡\n");
byte status; //存放返回值
byte myctrlword=0; //控制字
byte[] oldpicckey=new byte[4]; //认证密钥
byte[] mypiccserial=new byte[4]; //卡UID序列号
byte[] newpicckey=new byte[4]; //新密码
byte[] mynewuid=new byte[5]; //新4100卡号
boolean withkey=false; //是否要认证卡密钥
boolean thiscarduit =false; //是否只操作指定UID序号的卡
boolean addkey=false; //是否要开启密钥保护写入信息
if (withkey){ //本次操作需要密码验证,将认证密钥加入oldpicckey
myctrlword=(byte)(myctrlword+NEEDKEY);
String oldKeyhexstr="00000000"; //认证密钥
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="00000000"; //卡片uid
for(int i=0;i<4;i++){
mypiccserial[i]=(byte)Integer.parseInt(Uidhexstr.substring(i*2,(i+1)*2),16);
}
}
if(addkey){ //写入卡号后,是否要加密保护
String newkeyhexstr="00000000"; //新密钥
for(int i=0;i<4;i++){
newpicckey[i]=(byte)Integer.parseInt(newkeyhexstr.substring(i*2,(i+1)*2),16);
}
}
int NewUid=123456789; //要写入的4100十进制卡号
byte[] UidByte=int2byte(NewUid); //卡号转4字节数组
mynewuid[0]=0x27; //首字节为厂商代码
for (int i = 0; i < 4; i++) { //4字节卡号
mynewuid[1+i]=UidByte[i];
}
status = ouridr.em4305to4100(myctrlword,mypiccserial,oldpicckey,newpicckey,mynewuid);
if(status == 0) {
ouridr.beep(38);
String cardnohex = "";
for (int i = 0; i < 4; i++) {
String bytestr = "00" + Integer.toHexString(mypiccserial[i] & 0xff);
cardnohex = cardnohex + bytestr.substring(bytestr.length() - 2, bytestr.length());
}
System.out.print("将EM4305卡配置成ID卡成功!\n");
}else {
PrintErrInf(status); //错误代码提示
}
}
else if (args[0].equals("14")){ //轻松读HID卡
int status; //存放返回值
byte[] mypiccserial = new byte[7]; //7字节HID卡序列号缓冲
System.out.print("\n14-轻松读HID卡\n");
status = (int) (ouridr.hidread(mypiccserial ) & 0xff); //只要卡在感应区,每次执行此方法都可以读到卡号
System.out.print("结果:");
if (status == 0) {
ouridr.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("读取HID卡号成功!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("换算成10进制卡号:"+String.format("%010d", cardno10)+"\n");
} else {
PrintErrInf(status); //错误代码提示
}
}
}
//---------------------------------------------------------------------------------整数转4字节数组
public static byte[] int2byte(int res) {
byte[] targets = new byte[4];
targets[0] = (byte) (res & 0xff);// 最低位
targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
targets[2] = (byte) ((res >> 16) & 0xff);// 次高位
targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。
return targets;
}
//----------------------------------------------------------------------------------错误代码提示
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 4:
System.out.print("错误代码:4,卡放得远 或 需要密码才能读卡!\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;
}
}
//----------------------------------------------------------------------------------错误字符串代码提示
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);
}
}
}
package com.reader;
public class ouridr {
public native static byte beep(int xms);static{ //让设备发出声音
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte em4305init(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] configdata);static{ //写EM4305配置值,
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte em4305read(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] blockflag,byte[] blockdata);static{ //读EM4305卡,
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte em4305write(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] blockflag,byte[] blockdata);static{ //写EM4305卡,
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte em4305changekey(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] newkey);static{ //修改EM4305卡密钥,
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte em4305lock(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] lockflag);static{ //锁定EM4305卡块数据 ,
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte em4469init(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] configdata);static{ //写EM4469、4569卡配置值,
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte em4305to4100(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] newkey,byte[] newIDbuf);static{ //将EM4305卡配置成ID4100卡,
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte em4469tohid(byte ctrlword, byte[] mypiccserial,byte[] oldkey,byte[] newkey,byte[] newHIDbuf);static{ //将EM4460卡配置成ID、HID卡,
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
public native static byte hidread(byte[] mypiccserial );static{ //读HID卡
String osName = System.getProperty("os.name").toLowerCase();
if (osName.contains("windows")) {
System.load(System.getProperty("user.dir") + "/OUR_IDR.dll");
} else if (osName.contains("nix") || osName.contains("nux")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.so");
} else if (osName.contains("mac")) {
System.load(System.getProperty("user.dir") + "/libOURIDR.dylib");
}
}
}