zoukankan      html  css  js  c++  java
  • [转载]明华 IC卡应用 C#


    IC(Integrated Circuit)卡,也被称作智能卡(Smart Card),具有写入数据和存储数据的功能,IC卡内存储器的内容可以根据需要有条件地供外部读取,完成信息处理和判定。由于其内部具有集成电路,不但可以存储大量信息,具有极强的保密性能,并且还具有抗干扰、无磨损、寿命长等特性。因此在各个领域中得到广泛应用。下面通过两个实例介绍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毫秒。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_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);  //关闭设备

            }

  • 相关阅读:
    WSAAsyncSelect模型触发不了FD_Close消息?
    WSAAsyncSelect模型中,FD_WRITE事件什么时候触发?
    VC学习笔记:状态栏
    VC++对话框中加状态栏
    c++子类和父类成员函数重名
    vim学习笔记(11):vim 去掉<200b>
    tensorflow笔记5:tensorflow的基本运作,函数
    Anaconda的使用和包的更新;conda 创建虚拟环境
    vim学习笔记(10):vim命令大全
    tensorflow笔记4:函数:tf.assign()、tf.assign_add()、tf.identity()、tf.control_dependencies()
  • 原文地址:https://www.cnblogs.com/hehexiaoxia/p/2826323.html
Copyright © 2011-2022 走看看