ic卡

原创 2007年09月27日 09:04:00

13.3  IC卡应用

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

实例422 向IC卡中写入数据

实例说明

文本框: 图13.6  向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卡中的数据

实例说明

文本框: 图13.7  读取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卡制作考勤程序

实例说明

文本框: 图13.8  利用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 = "不存在该用户!";

            }

        }

举一反三

根据本实例,读者可以开发以下程序。

*  代金卡系统。

*  工资发放系统。

 

认证中心公钥(CA)与IC卡参数

认证中心公钥参数共包含如下参数信息:RID、认证中心公钥索引、认证中心公钥有效期、认证中心公钥哈什算法标识、认证中心公钥算法标识、认证中心公钥模、认证中心公钥指数、认证中心公钥校验值。 下面是对各参...

人民银行颁布《中国金融集成电路(IC)卡规范》

 日前,中国人民银行颁布《中国金融集成电路(IC)卡规范》(2010年版)(以下简称《规范》)。《规范》立足中国IC卡发展现状,汲取国际先进IC卡技术,总结国内金融IC卡试点经验,修制定了我国IC卡应...

非接触式IC卡的分类(三)

1、RF卡,即射频卡(或无线卡),是指应用RFID技术,就是感应式的,不需要接触到读卡器的卡片。 2、IC卡,可读可写,频率是13.56MHz的射频卡。现在所有的智能卡(接触的或非接的),都叫IC(集...

stm32芯片smartcard功能开发(接触式IC卡)

本文基于stm32l0c8t6芯片和cubemx,利用芯片USART1和USART2的smartcard功能,在不经过ST8024的情况下直接与IC卡和ESAM进行通讯处理。不使用ST8024的主要原...

IC卡安全操作基本命令-取随机数(GET CHALLENGE)

  出处: https://www.mianbaoban.cn/blog/post/38652   1、命令功能描述     该命令从卡片中取得一个任意长度(小于256Byte)的随...
  • LYX_WIN
  • LYX_WIN
  • 2017年12月01日 11:15
  • 32

一个IC卡数据准备tags解析器

自己2月份开发的一个代码解析器,负责解析只包涵tag的dp。 数据格式如下: [1] 57|8|62258821xxxxxxxx| 9F1F|2|2020| ... [2] 82|2|7...

IC卡个人化DDA过程日志

在IC卡认证过程中,最终极的的错误莫属DDA认证,由于涉及多次对称和非对称算法,所以碰到后一般都难以入手,PBOC规范写的比较凌乱,所以下面附一段机具和卡片的交互日志,有需要的可以配合一个加解密工具分...

金融IC卡非接触式快速支付的先天缺陷与补救措施

金融IC卡非接触式快速支付的先天缺陷与补救措施 1. 什么是脱机扣款失败交易     从客观现象来简单定义,脱机扣款失败交易是指持卡人在消费场所执行了一笔脱机消费交易,交易因某种原因未能成功,但...
  • juvary
  • juvary
  • 2017年05月31日 09:53
  • 373

非接触式IC卡性能简介(M1)

卡片的电气部分只由一个天线和ASIC组成。 天线:卡片的天线是只有几组绕线的线圈,很适于封装到IS0卡片中。 ASIC:卡片的ASIC由一个高速(106KB波特率)的RF接口,一个控制单元和一个 ...
  • YJB666
  • YJB666
  • 2014年06月12日 10:41
  • 645

基于NXP PN547 双界面IC卡读卡器解决方案

原文地址::http://www.wpgholdings.com/news/detail/zhcn/program/18810 相关文章 1、[讨论] PN544/PN547 NXP的NFC资料...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ic卡
举报原因:
原因补充:

(最多只允许输入30个字)