IC卡读写

来源:互联网 发布:淘宝7天打造爆款计划 编辑:程序博客网 时间:2024/04/30 16:39
IC卡应用
IC(Integrated Circuit)卡,也被称作智能卡(Smart Card),具有写入数据和存储数据的功能,IC卡内存储器的内容可以根据需要有条件地供外部读取,完成信息处理和判定。由于其内部具有集成电路,不但可以存储大量信息,具有极强的保密性能,并且还具有抗干扰、无磨损、寿命长等特性。因此在各个领域中得到广泛应用。下面通过两个实例介绍IC卡的简单应用。
实例422 向IC卡中写入数据
实例说明
IC卡是携带应用信息和数据的媒体,空白IC卡是不能立即使用的,必须对IC卡应用系统进行初始化,写入系统IC卡和个人密码,个人专用信息和应用数据。下面介绍如何向IC卡中写入数据。运行本例,在“数据”文本框中输入要存入IC卡中的数据,单击“写数据”按钮,即可将输入的数据写入IC卡中。如图13.6所示。

技术要点
本例使用的是深圳明华生产的明华IC卡读写器,用户在使用时将驱动程序安装完毕后,即可正常使用本系统。

本例通过调用Mwic_32.dll链接库,进行IC卡的读写工作。下面介绍与IC卡写操作相关的几个函数。
(1)auto_init函数
该函数用于初始化IC卡读卡器。语法如下:
public static extern int auto_init(int port, int baud);
参数说明如下。
l     port:标识端口号,Com1对应的端口号为0;Com2对应的端口号为1,依此类推。
l     baud:标识波特率。
l     返回值:如果初始化成功,返回值是IC卡设备句柄;如果初始化失败,返回值小于零。
(2)setsc_md函数
该函数用于设置设备密码模式。语法如下:
public static extern int setsc_md(int icdev, int mode);
参数说明如下。
l     icdev:标识设备句柄,通常是auto_init函数的返回值。
l     mode:标识设备密码模式,如果为0,设备密码有效,设备在加电时必须验证设备密码才能对设备进行操作。如果为1,设备密码无效。
l     返回值:如果函数执行成功返回值为零,否则小于零。
(3)get_status函数
该函数用于获取设备的当前状态。语法如下:
public static extern Int16 get_status(int icdev, Int16* state);
参数说明如下。
l     icdev:标识设备句柄,通常是auto_init函数的返回值。
l     state:用于接收函数返回的结果。如果为0表示读卡器中无卡,为1表示读卡器中有卡。
l     返回值:如果函数执行成功返回值为零,否则小于零。
(4)csc_4442函数
该函数用于核对IC卡密码。语法如下:
public static extern Int16 Csc_4442(int icdev, int len, [MarshalAs(UnmanagedType.LPArray)] byte[] p_string);
参数说明如下。
l     icdev:标识设备句柄,通常是auto_init函数的返回值。
l     len:标识密码长度,其值为3。
l     p_string:标识设置的密码。
l     返回值:如果函数执行成功返回值为零,否则小于零。
(5)swr_4442函数
该函数用于向IC卡中写入数据。语法如下:
public static extern int swr_4442(int icdev, int offset, int len, char* w_string);
参数说明如下。
l     icdev:标识设备句柄,通常是auto_init函数的返回值。
l     offset:标识地址的偏移量,范围是0~255。
l     len:标识字符串长度。
l     w_string:标识写入的数据。
(6)ic_exit函数
该函数用于关闭设备端口。语法如下:
public static extern int ic_exit(int icdev);
参数说明如下。
l     icdev:标识设备句柄,通常是auto_init函数的返回值。
(7)dv_beep函数
该函数使读卡器嗡鸣。语法如下:
public static extern int dv_beep(int icdev, int time);
参数说明如下。
l     icdev:标识设备句柄,通常是auto_init函数的返回值。
l     time:标识嗡鸣持续的时间,单位是10毫秒。
实现过程
(1)新建一个项目,命名为Ex13_05,默认窗体为Form1。

(2)在Form1窗体中,主要添加两个Button控件,用于执行向卡中写入数据和退出程序的操作,添加一个TextBox控件,将TextBox中数据写入IC卡中。
(3)主要程序代码。
将程序所使用的操作IC卡的函数,封装在类IC中。代码如下:
[StructLayout(LayoutKind.Sequential)]
public unsafe class IC
{
    //对设备进行初始化
    [DllImport("Mwic_32.dll", EntryPoint = "auto_init", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern int auto_init(int port, int baud);
    //设备密码格式
    [DllImport("Mwic_32.dll", EntryPoint = "setsc_md", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern int setsc_md(int icdev, int mode);
    //获取设备当前状态
    [DllImport("Mwic_32.dll", EntryPoint = "get_status", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern Int16 get_status(int icdev, Int16* state);
    //关闭设备通讯接口
    [DllImport("Mwic_32.dll", EntryPoint = "ic_exit", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern int ic_exit(int icdev);
    //使设备发出蜂鸣声
    [DllImport("Mwic_32.dll", EntryPoint = "dv_beep", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern int dv_beep(int icdev, int time);
    //向IC卡中写数据
    [DllImport("Mwic_32.dll", EntryPoint = "swr_4442", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern int swr_4442(int icdev, int offset, int len, char* w_string);
    //核对卡密码  
    [DllImport("Mwic_32.dll", EntryPoint = "csc_4442", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    public static extern Int16 Csc_4442(int icdev, int len, [MarshalAs(UnmanagedType.LPArray)] byte[] p_string);
}
下面代码主要用于将TextBox中数据写入到IC卡中。代码如下:
        private void button1_Click(object sender, EventArgs e)
        {
            //初始化
            int icdev = IC.auto_init(0, 9600);
            if (icdev < 0)
                MessageBox.Show("端口初始化失败,请检查接口线是否连接正确。","错误提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
            int md = IC.setsc_md(icdev, 1); //设备密码格式
            unsafe
            {
                Int16 status = 0;
                Int16 result = 0;
                result = IC.get_status(icdev, &status);
                if (result != 0)
                {
                    MessageBox.Show("设备当前状态错误!");
                    int d1 = IC.ic_exit(icdev);   //关闭设备
                    return;
                }
                if (status != 1)
                {
                    MessageBox.Show("请插入IC卡");
                    int d2 = IC.ic_exit(icdev);   //关闭设备
                    return;
                }
            }
            unsafe
            {
                //卡的密码默认为6个f(密码为:ffffff),1个f的16进制是15,两个f的16进制是255
                byte[] pwd = new byte[3] { 255, 255, 255 };
                //byte[] pwd = new byte[3] { 0xff, 0xff, 0xff };
                //char[] pass=new ch{0xff,0xff,0xff};
                Int16 checkIC_pwd = IC.Csc_4442(icdev, 3, pwd);
                if (checkIC_pwd < 0)
                {
                    MessageBox.Show("IC卡密码错误!");
                    return;
                }
                char str = 'a';
                int write=-1;
                for (int j = 0; j < textBox1.Text.Length; j++)
                {
                    str = Convert.ToChar(textBox1.Text.Substring(j, 1));
                    write = IC.swr_4442(icdev, 33 + j, textBox1.Text.Length, &str);
                }
                if (write == 0)
                {
                    int beep = IC.dv_beep(icdev, 20);  //发出蜂鸣声
                    MessageBox.Show("数据已成功写入IC卡中!");
                }
                else
                    MessageBox.Show("数据写入IC卡失败!");
            }
            int d = IC.ic_exit(icdev);  //关闭设备
        }
举一反三
根据本实例,读者可以实现以下功能。

  在图书借阅中使用IC卡。
  利用IC卡控制上网。
实例423 读取IC卡中的数据
实例说明
向IC卡写入数据后,就可以进行读卡操作了。运行本例,将写入数据的IC卡插入读卡器,单击【读卡】按钮,IC卡中的数据将显示在文本框中。如图13.7所示。

技术要点
本例中主要调用srd_4442函数读取IC卡中的数据,相关函数介绍请参考实例“向IC卡中写入数据”中的“技术要点”部分。这里只介绍读卡函数。

q srd_4442函数
该函数用于读取IC卡中的数据。语法如下:
public static extern int srd_4442(int icdev, int offset, int len, char* r_string);
参数说明如下。
l     icdev:标识设备句柄,通常是auto_init函数的返回值。
l     offset:标识地址的偏移量,范围是0~255。
l     len:标识字符串长度。
l     r_string:用于存储返回的数据。
实现过程
(1)新建一个项目,命名为Ex13_06,默认窗体为Form1。

(2)在Form1窗体中,主要添加两个Button控件,用于读取卡中的数据和退出程序,添加一个TextBox控件,显示卡中的数据。
(3)主要程序代码。
        private void button1_Click(object sender, EventArgs e)
        {
            //初始化
            int icdev = IC.auto_init(0, 9600);
            if (icdev < 0)
                MessageBox.Show("端口初始化失败,请检查接口线是否连接正确。", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            int md = IC.setsc_md(icdev, 1); //设备密码格式
            int i = IC.dv_beep(icdev, 10);  //发出蜂鸣声
            unsafe
            {
                Int16 status = 0;
                Int16 result = 0;
                result = IC.get_status(icdev, &status);
                if (result != 0)
                {
                    MessageBox.Show("设备当前状态错误!");
                    int d1 = IC.ic_exit(icdev);   //关闭设备
                    return;
                }
                if (status != 1)
                {
                    MessageBox.Show("请插入IC卡");
                    int d2 = IC.ic_exit(icdev);   //关闭设备
                    return;
                }
            }
            unsafe
            {
                char str = 'a';
                int read = -1;
                for (int j = 0; j < 6; j++)
                {
                    read = IC.srd_4442(icdev, 33 + j, 1, &str);
                    textBox1.Text = textBox1.Text + Convert.ToString(str);
                }
                if (read == 0)
                    MessageBox.Show("IC卡中数据读取成功!");
            }
            int d = IC.ic_exit(icdev);  //关闭设备
        }
举一反三
根据本实例,读者可以开发以下程序。

  读取IC卡电话系统。
  公交车刷卡系统。
实例424 利用IC卡制作考勤程序
实例说明
IC卡广泛应用于各行业,包括银行卡、公交车刷卡系统、读书卡等。下面介绍使用IC卡制作简单的公司考勤系统。运行本例,单击【刷卡】按钮,即可对员工进行考勤。实现效果如图13.8所示。

技术要点
有关IC卡的操作函数请参考实例“向IC卡中写入数据”和“读取IC卡中的数据”中的“技术要点”部分。

下面主要介绍通过IC卡如何实现员工考勤。主要将写入IC卡中的卡号读取出来,然后从数据表中查询员工信息。具体代码请参考实现过程。
实现过程
(1)新建一个项目,命名为Ex13_07,默认窗体为Form1。

(2)在Form1窗体中,主要添加5个TextBox控件和6个Label控件,用途如图13.7所示,添加一个Button控件,执行刷IC卡命令。
(3)主要程序代码。
        private void button1_Click(object sender, EventArgs e)
        {
            //初始化
            int icdev = IC.auto_init(0, 9600);
            if (icdev < 0)
                label6.Text = "端口初始化失败,请检查接口线是否连接正确。";
            unsafe
            {
                Int16 status = -1;
                Int16 result = IC.get_status(icdev, &status);
                int md = IC.setsc_md(icdev, 1);   //设备密码格式
                if (result < 0)
                {
                    int d1 = IC.ic_exit(icdev);  //关闭设备
                    return;
                }
                else if ((result == 0) && (status == 0))
                {
                    int d2 = IC.ic_exit(icdev);  //关闭设备
                    label6.Text = "请插入IC卡";
                    return;
                }
            }
            unsafe
            {
                char str = 'a';
                int read = -1;
                string ic = "";
                for (int j = 0; j < 6; j++)
                {
                    read = IC.srd_4442(icdev, 33 + j, 1, &str);
                    ic = ic + Convert.ToString(str);
                }
                textBox1.Text = ic;
                if (read == 0)
                    label6.Text = "刷卡成功!";
                int beep = IC.dv_beep(icdev, 20);  //发出蜂鸣声
                int d3 = IC.ic_exit(icdev);   //关闭设备
            }
            int d = IC.ic_exit(icdev);  //关闭设备
            //根据卡号,查找相应数据
            OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + "price.mdb" + ";Persist Security Info=False");
            OleDbDataAdapter dap = new OleDbDataAdapter("select * from worker where ICID='"+textBox1.Text+"'", con);
            DataSet ds = new DataSet();
            dap.Fill(ds, "table");
            if (ds.Tables.Count > 0)
            {
                textBox2.Text = ds.Tables[0].Rows[0][0].ToString();
                textBox3.Text = ds.Tables[0].Rows[0][1].ToString();
                textBox4.Text = ds.Tables[0].Rows[0][2].ToString();
                textBox5.Text = ds.Tables[0].Rows[0][3].ToString();
            }
            else
            {
                label6.Text = "不存在该用户!";
            }
        }
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 铜钱的字不认识怎么办 古钱币出手好烦怎么办 安装目录不可写怎么办 手机不支持exfat格式怎么办 windows7图标变大了怎么办 igs格式烂曲面怎么办 手机桌面文件夹打不开怎么办 苹果下载不了150怎么办 iphone6速度变慢怎么办 苹果手机微信打不开pdf怎么办 苹果手机打不开pdf怎么办 pdf文件超过了怎么办 pdf电脑删不了怎么办 联想笔记本摄像头横屏调竖屏怎么办 pdf文件打开失败怎么办 pdf复制文字乱码怎么办 电子发票乱码了怎么办 超星尔雅挂了怎么办 电脑应用双击打不开怎么办 电脑控制面板打不开怎么办 转换器无法打开文件怎么办 电脑文件无法打开怎么办 手机上jpg打不开怎么办 脸上全是黄褐斑怎么办 容易发胖的体质怎么办 感冒后一直咳嗽怎么办 感冒咳嗽怎么办小窍门 到了减肥平台期怎么办 减肥遇见平台期怎么办 脚冻伤了痒怎么办 冬天脚后跟冻了怎么办 夏天脚冻了怎么办 导航软件删了怎么办 婆婆爱打孩子怎么办 乙肝婆婆带孩子怎么办 婆婆不会教孩子怎么办 婆婆不会带孩子怎么办 公婆枪带孩子怎么办 婆婆要带孩子怎么办 婆婆太惯孩子怎么办 三个月宝宝溢奶怎么办