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卡的复制,其内部存储结构如下图:
本示例使用的发卡器
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);
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
- 298.
- 299.
- 300.
- 301.
- 302.
- 303.
- 304.
- 305.
- 306.
- 307.
- 308.
- 309.
- 310.
- 311.
- 312.
- 313.
- 314.
- 315.
- 316.
- 317.
- 318.
- 319.
- 320.
- 321.
- 322.
- 323.
- 324.
- 325.
- 326.
- 327.
- 328.
- 329.
- 330.
- 331.
- 332.
- 333.
- 334.
- 335.
- 336.
- 337.
- 338.
- 339.
- 340.
- 341.
- 342.
- 343.
- 344.
- 345.
- 346.
- 347.
- 348.
- 349.
- 350.
- 351.
- 352.
- 353.
- 354.
- 355.
- 356.
- 357.
- 358.
- 359.
- 360.
- 361.
- 362.
- 363.
- 364.
- 365.
- 366.
- 367.
- 368.
- 369.
- 370.
- 371.
- 372.
- 373.
- 374.
- 375.
- 376.
- 377.
- 378.
- 379.
- 380.
- 381.
- 382.
- 383.
- 384.
- 385.
- 386.
- 387.
- 388.
- 389.
- 390.
- 391.
- 392.
- 393.
- 394.
- 395.
- 396.
- 397.
- 398.
- 399.
- 400.
- 401.
- 402.
- 403.
- 404.
- 405.
- 406.
- 407.
- 408.
- 409.
- 410.
- 411.
- 412.
- 413.
- 414.
- 415.
- 416.
- 417.
- 418.
- 419.
- 420.
- 421.
- 422.
- 423.
- 424.
- 425.
- 426.
- 427.
- 428.
- 429.
- 430.
- 431.
- 432.
- 433.
- 434.
- 435.
- 436.
- 437.
- 438.
- 439.
- 440.
- 441.
- 442.
- 443.
- 444.
- 445.
- 446.
- 447.
- 448.
- 449.
- 450.
- 451.
- 452.
- 453.
- 454.
- 455.
- 456.
- 457.
- 458.
- 459.
- 460.
- 461.
- 462.
- 463.
- 464.
- 465.
- 466.
- 467.
- 468.
- 469.
- 470.
- 471.
- 472.
- 473.
- 474.
- 475.
- 476.
- 477.
- 478.
- 479.
- 480.
- 481.
- 482.
- 483.
- 484.
- 485.
- 486.
- 487.
- 488.
- 489.
- 490.
- 491.
- 492.
- 493.
- 494.
- 495.
- 496.
- 497.
- 498.
- 499.
- 500.
- 501.
- 502.
- 503.
- 504.
- 505.
- 506.
- 507.
- 508.
- 509.
- 510.
- 511.
- 512.
- 513.
- 514.
- 515.
- 516.
- 517.
- 518.
- 519.
- 520.
- 521.
- 522.
- 523.
- 524.
- 525.
- 526.
- 527.
- 528.
- 529.
- 530.
- 531.
- 532.
- 533.
- 534.
- 535.
- 536.
- 537.
- 538.
- 539.
- 540.
- 541.
- 542.
- 543.
- 544.
- 545.
- 546.
- 547.
- 548.
- 549.
- 550.
- 551.
- 552.
- 553.
- 554.
- 555.
- 556.
- 557.
- 558.
- 559.
- 560.
- 561.
- 562.
- 563.
- 564.
- 565.
- 566.
- 567.
- 568.
- 569.
- 570.
- 571.
- 572.
- 573.
- 574.
- 575.
- 576.
- 577.
- 578.
- 579.
- 580.
- 581.
- 582.
- 583.
- 584.
- 585.
- 586.
- 587.
- 588.
- 589.
- 590.
- 591.
- 592.
- 593.
- 594.
- 595.
- 596.
- 597.
- 598.
- 599.
- 600.
- 601.
- 602.
- 603.
- 604.
- 605.
- 606.
- 607.
- 608.
- 609.
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");
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.