Java读写EM4305卡、将4305卡制做成4100ID卡

        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");
        }
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vx_13822155058

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值