C#读写EM4205/4305/4469卡复制ID卡源码

  本示例使用的发卡器:EM4305 EM4469 ISO11784/85协议125K低频FXD-B动物标签读写发卡器-淘宝网 (taobao.com)

        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卡的复制。

 函数声明

 //------------------------------------------------------------------------------------------------------------------------------------------------------
        //外部函数声明:让设备发出声响
        [DllImport("OUR_IDR.dll", EntryPoint = "idr_beep", CallingConvention = CallingConvention.StdCall)]
        static extern byte idr_beep(UInt32 xms);//xms单位为毫秒 
        //------------------------------------------------------------------------------------------------------------------------------------------------------    
        //读取设备编号,可做为软件加密狗用,也可以根据此编号在公司网站上查询保修期限
        [DllImport("OUR_IDR.dll", EntryPoint = "pcdgetdevicenumber", CallingConvention = CallingConvention.StdCall)]
        static extern byte pcdgetdevicenumber(byte[] devicenumber);//devicenumber用于返回编号 
        //------------------------------------------------------------------------------------------------------------------------------------------------------    
        //只读EM4100卡号
        [DllImport("OUR_IDR.dll", EntryPoint = "idr_read", CallingConvention = CallingConvention.StdCall)]
        public static extern byte idr_read(byte[] serial);//serial返回卡号        
        //------------------------------------------------------------------------------------------------------------------------------------------------------    
        //只读卡号,只读一次EM4100卡,必须拿开卡才能再读到
        [DllImport("OUR_IDR.dll", EntryPoint = "idr_read_once", CallingConvention = CallingConvention.StdCall)]
        public static extern byte idr_read_once(byte[] serial);//serial返回卡号
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //EM4205/4305卡写配置块
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_init", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_init(byte ctrlword, byte[] seria, byte[] key, byte[] configdata);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //EM4469/4569卡写配置块
        [DllImport("OUR_IDR.dll", EntryPoint = "em4469_init", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4469_init(byte ctrlword, byte[] seria, byte[] key, byte[] configdata);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //EM4205/4305/4469/4569卡读卡
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_read", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_read(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag, byte[] readdata);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //EM4205/4305/4469/4569卡写卡
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_write", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_write(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag, byte[] writedata);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //EM4205/4305/4469/4569卡锁定块
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_lock", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_lock(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //EM4205/4305/4469/4569卡改密码
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_changekey", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_changekey(byte ctrlword, byte[] seria, byte[] oldkey, byte[] newkey);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //用EM4205/4305卡制作ID卡(也就是EM4100及兼容卡)
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_to4100", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_to4100(byte ctrlword, byte[] seria, byte[] oldkey, byte[] newkey, byte[] myuidbuf);
        //-----------------------------------------------------------------------------------------------------------------------------------------------------        
        //只读HID卡号
        [DllImport("OUR_IDR.dll", EntryPoint = "hid_read", CallingConvention = CallingConvention.StdCall)]
        public static extern byte hid_read(byte[] serial);//serial返回卡号 

读取EM4205/4305/4469/4569芯片内数据

 byte status;     //存放返回值
            int j;
            byte myctrlword = 0x00;  //控制字
            byte[] oldpicckey = new byte[4];  //密码
            byte[] mypiccserial = new byte[4];  //卡序列号
            byte[] mypiccdata = new byte[70];  //读卡数据缓冲:卡无线转输分频比、卡内容长度(字节数),及最多返回12个块的数据
            byte[] mypiccblockflag = new byte[2]; //指定读哪一块
            string PasswStr = textBox14.Text.Trim();
            string seriaStr = textBox15.Text.Trim();

            if (checkBox1.Checked)  //本次操作需要密码验证
            {
                myctrlword = (byte)(myctrlword + NEEDKEY);
                try
                {
                    oldpicckey[0] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(0, 2), 16));
                    oldpicckey[1] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(2, 2), 16));
                    oldpicckey[2] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(4, 2), 16));
                    oldpicckey[3] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(6, 2), 16));
                }
                catch
                {
                    MessageBox.Show("认证密码输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textBox14.Select();
                    return;
                }
            }

            if (checkBox2.Checked)  //仅操作指定卡号的卡
            {
                try
                {
                    myctrlword = (byte)(myctrlword + NEEDSERIAL);
                    mypiccserial[0] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(0, 2), 16));
                    mypiccserial[1] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(2, 2), 16));
                    mypiccserial[2] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(4, 2), 16));
                    mypiccserial[3] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(6, 2), 16));
                }
                catch
                {
                    MessageBox.Show("卡号输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textBox15.Select();
                    return;
                }
            }

            j = 0;
            mypiccblockflag[0] = 0x00;
            for (int i = 0; i < 8; i++)
            {
                if (myCheckBox[i].Checked)
                {
                    mypiccblockflag[0] = (byte)(mypiccblockflag[0] + Math.Pow(2, i));
                    j++;
                }
            }

            mypiccblockflag[1] = 0x00;
            for (int i = 0; i < 8; i++)
            {
                if (myCheckBox[8 + i].Checked)
                {
                    mypiccblockflag[1] = (byte)(mypiccblockflag[1] + Math.Pow(2, i));
                    j++;
                }
            }

            status = em4305_read(myctrlword, mypiccserial, oldpicckey, mypiccblockflag, mypiccdata);
            if (status == 0)
            {
                string blockdata = "";
                for (int i = 0; i < mypiccdata[1]; i++)
                {
                    blockdata = blockdata + mypiccdata[2 + i].ToString("X2");
                }
                textBox4.Text = blockdata;

                j = 0;
                for (int i = 0; i < 16; i++)
                {
                    if (myCheckBox[i].Checked)
                    {
                        myTextBox[i].Text = blockdata.Substring(j, 8);
                        j = j + 8;
                    }
                }

                seriaStr = "";
                for (int i = 0; i < 4; i++)
                {
                    seriaStr = seriaStr + mypiccserial[i].ToString("X2");
                }
                idr_beep(30);
                MessageBox.Show("读卡成功,卡无线转输分频比:" + mypiccdata[0].ToString("D") + ",卡号:" + seriaStr, "提示:", MessageBoxButtons.OK, MessageBoxIcon.Information);


            }
            else { MessageErrInf(status); }

写数据到EM4205/4305/4469/4569芯片内

byte status;     //存放返回值
            int j;
            byte myctrlword = 0x00;               //控制字
            byte[] oldpicckey = new byte[4];      //密码
            byte[] mypiccserial = new byte[4];    //卡序列号
            byte[] mypiccdata = new byte[50];     //写卡数据缓冲
            byte[] mypiccblockflag = new byte[2]; //指定读哪一块
            string PasswStr = textBox14.Text.Trim();
            string seriaStr = textBox15.Text.Trim();

            int chtxt = Form1_chedkdata();
            if (chtxt != 100)
            {
                MessageBox.Show("写卡数据输入错误,请重新输入!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                myTextBox[chtxt].Select();
                return;
            }

            if (checkBox1.Checked)  //本次操作需要密码验证
            {
                myctrlword = (byte)(myctrlword + NEEDKEY);
                try
                {
                    oldpicckey[0] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(0, 2), 16));
                    oldpicckey[1] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(2, 2), 16));
                    oldpicckey[2] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(4, 2), 16));
                    oldpicckey[3] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(6, 2), 16));
                }
                catch
                {
                    MessageBox.Show("认证密码输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textBox14.Select();
                    return;
                }
            }

            if (checkBox2.Checked)  //仅操作指定卡号的卡
            {
                try
                {
                    myctrlword = (byte)(myctrlword + NEEDSERIAL);
                    mypiccserial[0] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(0, 2), 16));
                    mypiccserial[1] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(2, 2), 16));
                    mypiccserial[2] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(4, 2), 16));
                    mypiccserial[3] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(6, 2), 16));
                }
                catch
                {
                    MessageBox.Show("卡号输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textBox15.Select();
                    return;
                }
            }

            if (myCheckBox[1].Checked)
            {
                MessageBox.Show("块1为uid块,只能读取不可写入!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (myCheckBox[4].Checked)
            {
                MessageBox.Show("块4为配置区,只能在初始化函数中操作!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (myCheckBox[14].Checked)
            {
                MessageBox.Show("块14为锁定标志块,只能在初始化函数中操作!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (myCheckBox[15].Checked)
            {
                MessageBox.Show("块15为配置区,只能在初始化函数中操作!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            j = 0;
            string WriteStr = "";

            mypiccblockflag[0] = 0x00;
            for (int i = 0; i < 8; i++)
            {
                if (myCheckBox[i].Checked)
                {
                    mypiccblockflag[0] = (byte)(mypiccblockflag[0] + Math.Pow(2, i));
                    WriteStr = WriteStr + myTextBox[i].Text;
                    j++;
                }
            }

            mypiccblockflag[1] = 0x00;
            for (int i = 0; i < 8; i++)
            {
                if (myCheckBox[8 + i].Checked)
                {
                    mypiccblockflag[1] = (byte)(mypiccblockflag[1] + Math.Pow(2, i));
                    WriteStr = WriteStr + myTextBox[8 + i].Text;
                    j++;
                }
            }

            for (int i = 0; i < WriteStr.Length / 2; i++)
            {
                mypiccdata[i] = Convert.ToByte(Convert.ToInt32(WriteStr.Substring(i * 2, 2), 16));
            }

            status = em4305_write(myctrlword, mypiccserial, oldpicckey, mypiccblockflag, mypiccdata);
            if (status == 0)
            {
                seriaStr = "";
                for (int i = 0; i < 4; i++)
                {
                    seriaStr = seriaStr + mypiccserial[i].ToString("X2");
                }
                idr_beep(30);
                MessageBox.Show("卡号:" + seriaStr + "写卡成功!", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else { MessageErrInf(status); }

将EM4205/4305卡制做成ID门禁卡

 byte status;     //存放返回值
            byte myctrlword = 0x00;  //控制字
            byte[] oldpicckey = new byte[4];  //密码
            byte[] newpicckey = new byte[4];  //新密码
            byte[] mypiccserial = new byte[6];  //卡序列号

            byte[] mypiccblockflag = new byte[2]; //指定读哪一块
            string PasswStr = textBox14.Text.Trim();
            string seriaStr = textBox15.Text.Trim();
            string newpassw = textBox20.Text.Trim();
            string newuidstr = textBox3.Text.Trim();

            if (checkBox1.Checked)  //本次操作需要密码验证
            {
                myctrlword = (byte)(myctrlword + NEEDKEY);
                try
                {
                    oldpicckey[0] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(0, 2), 16));
                    oldpicckey[1] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(2, 2), 16));
                    oldpicckey[2] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(4, 2), 16));
                    oldpicckey[3] = Convert.ToByte(Convert.ToInt32(PasswStr.Substring(6, 2), 16));
                }
                catch
                {
                    MessageBox.Show("认证密码输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textBox14.Select();
                    return;
                }
            }

            if (checkBox2.Checked)  //仅操作指定卡号的卡
            {
                try
                {
                    myctrlword = (byte)(myctrlword + NEEDSERIAL);
                    mypiccserial[0] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(0, 2), 16));
                    mypiccserial[1] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(2, 2), 16));
                    mypiccserial[2] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(4, 2), 16));
                    mypiccserial[3] = Convert.ToByte(Convert.ToInt32(seriaStr.Substring(6, 2), 16));
                }
                catch
                {
                    MessageBox.Show("卡号输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textBox15.Select();
                    return;
                }
            }

            if (checkBox11.Checked)  //修改卡片密码
            {
                try
                {
                    myctrlword = (byte)(myctrlword + KEYENABLE);
                    newpicckey[0] = Convert.ToByte(Convert.ToInt32(newpassw.Substring(0, 2), 16));
                    newpicckey[1] = Convert.ToByte(Convert.ToInt32(newpassw.Substring(2, 2), 16));
                    newpicckey[2] = Convert.ToByte(Convert.ToInt32(newpassw.Substring(4, 2), 16));
                    newpicckey[3] = Convert.ToByte(Convert.ToInt32(newpassw.Substring(6, 2), 16));
                }
                catch
                {
                    MessageBox.Show("密码输入错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textBox20.Select();
                    return;
                }
            }

            if (radioButton3.Checked)
            {
                if (newuidstr.Length != 10 || !checkhex(newuidstr)) { MessageBox.Show("要写入的10位16进制卡号错误,请输入正确的10位16进制卡号!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }
                byte[] myuid = new byte[5];        //写入的新卡号
                try
                {
                    myuid[0] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(0, 2), 16));
                    myuid[1] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(2, 2), 16));
                    myuid[2] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(4, 2), 16));
                    myuid[3] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(6, 2), 16));
                    myuid[4] = Convert.ToByte(Convert.ToInt32(newuidstr.Substring(8, 2), 16));
                }
                catch
                {
                    MessageBox.Show("新卡号输入错误,请输入8位16进制数的卡号!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textBoxuid1.Select();
                    return;
                }

                status = em4305_to4100(myctrlword, mypiccserial, oldpicckey, newpicckey, myuid);
                if (status == 0)
                {
                    idr_beep(50);
                    MessageBox.Show("卡号:" + System.Convert.ToString(myuid[1] * 256 * 256 * 256 + myuid[2] * 256 * 256 + myuid[3] * 256 + myuid[4]) + " 写卡成功变成ID卡!", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else { MessageErrInf(status); }
            }
            else
            {
                MessageBox.Show("此功能暂未开发!", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

vx_13822155058

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

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

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

打赏作者

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

抵扣说明:

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

余额充值