读取身份证

    这份代码,主要是根据api文档来写的,文档上提供了各个方法的使用说明,并且有一个示例代码。以及网上找到的代码。

    首先,需要2dllsdtapi.dll,用来读取身份证上的基本信息;WltRS.dll,用来解析照片,身份证上的照片。这两个文件放在bin目录的debug中,或者release中。然后对于sdtapi.dll该动态链接库,若用的是2004年左右的,需要一个temp.lib的授权文件;但是2005年左右的,则不需要了。

    然后引入动态链接库中的方法,里面的方法都是参考网上的资料和文档写出来的。新建一个名叫DllMoudle的类,里面有7个方法,通过DllImport链接库导入,导入。方法主要是SDT_OpenPort,打开端口号和 SDT_ClosePort关闭端口号,SDT_StartFindIDCard开始找卡,SDT_SelectIDCard选择卡,以及SDT_ReadBaseMsg读取基本信息,和 SDT_ReadBaseMsgToFile从文件中读取基本信息,以及GetBmp获取图片。

 public class DllMoudle
    {
        #region "dll声明"
        /// <summary>
        /// 打开串口/USB。 
        /// </summary>
        /// <param name="iPort">[in] 整数, 表示端口号。 1-16(十进制)为串口,1001-1016(十进制)为USB口,缺省的一个USB 设备端口号是 1001。</param>
        /// <returns>0x90 打开端口成功;1 打开端口失败/端口号不合法</returns>
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_OpenPort(int iPort);
        /// <summary>
        /// 关闭串口/USB。
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。</param>
        /// <returns>0x90 关闭端口成功。 0x01 端口号不合法</returns>
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ClosePort(int iPort);
        /// <summary>
        /// 读卡
        /// </summary>
        /// <param name="iPort"></param>
        /// <param name="pucManaInfo">证/卡芯片管理号, 4 个字节。</param>
        /// <param name="iIfOpen"></param>
        /// <returns>0x9f 找卡成功;0x80 找卡失败</returns>
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_StartFindIDCard (int iPort,  byte[] pucManaInfo,int iIfOpen);
        /// <summary>
        /// 选择卡
        /// </summary>
        /// <param name="iPort"></param>
        /// <param name="pucManaMsg">卡体管理号,28 字节。</param>
        /// <param name="iIfOpen"></param>
        /// <returns>0x90 读成功;其他 读失败(具体含义参见返回码表</returns>
        [DllImport("sdtapi.dll",CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_SelectIDCard (int iPort , byte[] pucManaMsg,int iIfOpen);
        /// <summary>
        /// 读取基本数据
        /// </summary>
        /// <param name="iPort"></param>
        /// <param name="pucCHMsg"></param>
        /// <param name="puiCHMsgLen"></param>
        /// <param name="pucPHMsg"></param>
        /// <param name="puiPHMsgLen"></param>
        /// <param name="iIfOpen"></param>
        /// <returns></returns>
        [DllImport("sdtapi.dll",CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ReadBaseMsg(int iPort, byte[] pucCHMsg, ref UInt32 puiCHMsgLen, byte[] pucPHMsg, ref UInt32 puiPHMsgLen, int iIfOpen);
        /// <summary>
        /// 读取图片;
        /// </summary>
        /// <param name="file_name">wlt文件名,后缀是.wlt</param>
        /// <param name="Port"></param>
        /// <returns>1,正确;0,-1,-2,。。。-6</returns>
        [DllImport("WltRS.dll",CallingConvention = CallingConvention.StdCall)]
        public static extern int GetBmp(String file_name, int Port);
        [DllImport("sdtapi.dll")]
        public static extern int SDT_ReadBaseMsgToFile(int iPortID, string fileName1, ref UInt32 puiCHMsgLen, string fileName2, ref UInt32 puiPHMsgLen, int iIfOpen);
        #endregion

    }

    现在这些方法就可以用了。

    然后建立了一个实体clsEDZ,用来存放身份证上的基本信息。包括图片,二进制的和Image的。还有由于身份证上sexnation读取到的都是code,根据code,拿到真正的值。如sex若是1,则是男;民族若是01,则是汉族。

public class clsEDZ
    {
        private SortedList lstMZ = new SortedList();
        private string _Name;                      //姓名
        private string _Sex_Code;                  //性别代码
        private string _Sex_CName;                 //性别
        private string _IDC;                       //身份证号码
        private string _NATION_Code;               //民族代码
        private string _NATION_CName;              //民族
        private DateTime _BIRTH;                   //出生日期
        private string _ADDRESS;                   //住址
        private string _REGORG;                    //签发机关
        private DateTime _STARTDATE;               //身份证有效起始日期
        private DateTime _ENDDATE;                 //身份证有效截至日期
        private string _Period_Of_Validity_Code;   //有效期限代码,许多原来系统上面为了一代证考虑,常常存在这样的字段,二代证中已经没有了
        private string _Period_Of_Validity_CName;  //有效期限
        private byte[] _PIC_Byte;                  //照片二进制
        private Image _PIC_Image;                 //照片

        public clsEDZ()
        {
            lstMZ.Add("01", "汉族");
            lstMZ.Add("02", "蒙古族");
            lstMZ.Add("03", "回族");
            lstMZ.Add("04", "藏族");
            lstMZ.Add("05", "维吾尔族");
            lstMZ.Add("06", "苗族");
            lstMZ.Add("07", "彝族");
            lstMZ.Add("08", "壮族");
            lstMZ.Add("09", "布依族");
            lstMZ.Add("10", "朝鲜族");
            lstMZ.Add("11", "满族");
            lstMZ.Add("12", "侗族");
            lstMZ.Add("13", "瑶族");
            lstMZ.Add("14", "白族");
            lstMZ.Add("15", "土家族");
            lstMZ.Add("16", "哈尼族");
            lstMZ.Add("17", "哈萨克族");
            lstMZ.Add("18", "傣族");
            lstMZ.Add("19", "黎族");
            lstMZ.Add("20", "傈僳族");
            lstMZ.Add("21", "佤族");
            lstMZ.Add("22", "畲族");
            lstMZ.Add("23", "高山族");
            lstMZ.Add("24", "拉祜族");
            lstMZ.Add("25", "水族");
            lstMZ.Add("26", "东乡族");
            lstMZ.Add("27", "纳西族");
            lstMZ.Add("28", "景颇族");
            lstMZ.Add("29", "柯尔克孜族");
            lstMZ.Add("30", "土族");
            lstMZ.Add("31", "达翰尔族");
            lstMZ.Add("32", "仫佬族");
            lstMZ.Add("33", "羌族");
            lstMZ.Add("34", "布朗族");
            lstMZ.Add("35", "撒拉族");
            lstMZ.Add("36", "毛南族");
            lstMZ.Add("37", "仡佬族");
            lstMZ.Add("38", "锡伯族");
            lstMZ.Add("39", "阿昌族");
            lstMZ.Add("40", "普米族");
            lstMZ.Add("41", "塔吉克族");
            lstMZ.Add("42", "怒族");
            lstMZ.Add("43", "乌孜别克族");
            lstMZ.Add("44", "俄罗斯族");
            lstMZ.Add("45", "鄂温克族");
            lstMZ.Add("46", "德昂族");
            lstMZ.Add("47", "保安族");
            lstMZ.Add("48", "裕固族");
            lstMZ.Add("49", "京族");
            lstMZ.Add("50", "塔塔尔族");
            lstMZ.Add("51", "独龙族");
            lstMZ.Add("52", "鄂伦春族");
            lstMZ.Add("53", "赫哲族");
            lstMZ.Add("54", "门巴族");
            lstMZ.Add("55", "珞巴族");
            lstMZ.Add("56", "基诺族");
            lstMZ.Add("57", "其它");
            lstMZ.Add("98", "外国人入籍");
        }

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
        public string Sex_Code
        {
            get { return _Sex_Code; }
            set
            {
                _Sex_Code = value;
                switch (value)
                {
                    case "1":
                        Sex_CName = "男";
                        break;
                    case "2":
                        Sex_CName = "女";
                        break;
                }
            }
        }
        public string Sex_CName
        {
            get { return _Sex_CName; }
            set { _Sex_CName = value; }
        }
        public string IDC
        {
            get { return _IDC; }
            set { _IDC = value; }
        }
        public string NATION_Code
        {
            get { return _NATION_Code; }
            set
            {
                _NATION_Code = value;
                if (lstMZ.Contains(value))
                    NATION_CName = lstMZ[value].ToString();
            }
        }
        public string NATION_CName
        {
            get { return _NATION_CName; }
            set { _NATION_CName = value; }
        }
        public DateTime BIRTH
        {
            get { return _BIRTH; }
            set { _BIRTH = value; }
        }
        public string ADDRESS
        {
            get { return _ADDRESS; }
            set { _ADDRESS = value; }
        }
        public string REGORG
        {
            get { return _REGORG; }
            set { _REGORG = value; }
        }
        public DateTime STARTDATE
        {
            get { return _STARTDATE; }
            set { _STARTDATE = value; }
        }
        public DateTime ENDDATE
        {
            get { return _ENDDATE; }
            set
            {
                _ENDDATE = value;
                if (_ENDDATE == DateTime.MaxValue)
                {
                    _Period_Of_Validity_Code = "3";
                    _Period_Of_Validity_CName = "长期";
                }
                else
                {
                    if (_STARTDATE != DateTime.MinValue)
                    {
                        switch (value.AddDays(1).Year - _STARTDATE.Year)
                        {
                            case 5:
                                _Period_Of_Validity_Code = "4";
                                _Period_Of_Validity_CName = "5年";
                                break;
                            case 10:
                                _Period_Of_Validity_Code = "1";
                                _Period_Of_Validity_CName = "10年";
                                break;
                            case 20:
                                _Period_Of_Validity_Code = "2";
                                _Period_Of_Validity_CName = "20年";
                                break;
                        }
                    }
                }

            }
        }
        public string Period_Of_Validity_Code
        {
            get { return _Period_Of_Validity_Code; }
            set { _Period_Of_Validity_Code = value; }
        }
        public string Period_Of_Validity_CName
        {
            get { return _Period_Of_Validity_CName; }
            set { _Period_Of_Validity_CName = value; }
        }
        public byte[] PIC_Byte
        {
            get { return _PIC_Byte; }
            set { _PIC_Byte = value; }
        }
        public Image PIC_Image
        {
            get { return _PIC_Image; }
            set { _PIC_Image = value; }
        }
 

    }
    再新建一个窗体readIdCard。在页面上加上一个文本框和button按钮,按钮点击一下读一下身份证信息,文本框显示返回的身份证信息。然后还有一个picturebox放照片。

public partial class readIdCard : Form
    {
        //接收身份证信息的实体
        private clsEDZ objEDZ = new clsEDZ();

        //构造函数
        public readIdCard()
        {
            InitializeComponent();
        }

        //读卡
        private void button1_Click(object sender, EventArgs e)
        {
                usbIdCard();
        }

        private void usbIdCard() {
            //声明变量
            DialogResult dr;
            int iRet    = 0x90;          //返回码
            int iPort   = 1001;          //端口号
            int iIfOpen =  1;             //是否需要打开端口
            byte[] pubManaInfo = new byte[255];    //身份证管理号信息
            byte[] pubManaMsg  = new byte[255];    //
            byte[] pubCHMsg    = new byte[512];  //文字信息
            byte[] pubPHMsg    = new byte[3024]; //照片信息
            byte[] pubFPMsg    = new byte[1024]; //指纹信息
            UInt32 puiCHMsgLen = 0;              //文字信息的长度
            UInt32 puiPHMsgLen = 0;              //照片信息的长度

            //打开端口
            if (iIfOpen == 0) {
                iRet = DllMoudle.SDT_OpenPort(iPort);
                //若打开端口不成功
                if (iRet != 0x90) {
                    MessageBox.Show("SDT_OpenPort Error,Error Code Is: " + iRet);
                    //关闭端口
                    DllMoudle.SDT_ClosePort(iPort);
                    return;
                }
            }
            
            //找卡
            do {
                //开始找卡
                iRet = DllMoudle.SDT_StartFindIDCard(iPort, pubManaInfo, iIfOpen);

                if(iRet == 0x9f){
                    //找到之后,选择卡
                    iRet = DllMoudle.SDT_SelectIDCard(iPort, pubManaMsg, iIfOpen);
                    if (iRet == 0x90) {
                        break;
                    }
                }

                //若找不到卡,提示
                dr = MessageBox.Show("尚未找到卡,您是否想继续找卡?", "找卡提示",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);
            } 
            //一直找卡,直到取消找卡
            while ( dr == DialogResult.Yes);

            //读卡信息
            iRet = DllMoudle.SDT_ReadBaseMsg(iPort, pubCHMsg,ref puiCHMsgLen,pubPHMsg,ref puiPHMsgLen,iIfOpen);
            if (iRet != 0x90) {
                //不成功,关闭端口,退出
                MessageBox.Show("SDT_ReadBaseMsg Error,Error Code Is: " + iRet);
                closePort(iPort, iIfOpen);
                return;
            }

            //读卡成功
            //显示结果集
            textBox1.Text = System.Text.ASCIIEncoding.Unicode.GetString(pubCHMsg);
             
            //注意,在这里,用户必须有应用程序当前目录的读写权限
            //删除掉这些文件
            FileInfo objFile = new FileInfo("wz.txt");
            if (objFile.Exists)
            {
                objFile.Attributes = FileAttributes.Normal;
                objFile.Delete();
            }
            objFile = new FileInfo("zp.bmp");
            if (objFile.Exists)
            {
                objFile.Attributes = FileAttributes.Normal;
                objFile.Delete();
            }
            objFile = new FileInfo("zp.wlt");
            if (objFile.Exists)
            {
                objFile.Attributes = FileAttributes.Normal;
                objFile.Delete();
            }

            //将基本信息写到wz.txt中,将照片信息写到zp.wlt文件中
            iRet = DllMoudle.SDT_ReadBaseMsgToFile(iPort, "wz.txt", ref puiCHMsgLen, "zp.wlt", ref puiPHMsgLen, iIfOpen);
            if (iRet != 144)
            {
                iRet = DllMoudle.SDT_ClosePort(iPort);
                MessageBox.Show("读卡失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }


            //下面解析照片,注意,如果在C盘根目录下没有机具厂商的授权文件Termb.Lic,照片解析将会失败
            //用2表示usb口,1表示串口。将zp.wlt转换为照片zp.bmp。
            bool falg = true;
            if (falg)
                iRet = DllMoudle.GetBmp("zp.wlt", 2);
            else
                iRet = DllMoudle.GetBmp("zp.wlt", 1);
            switch (iRet)
            {
                case 0:
                    MessageBox.Show("调用sdtapi.dll错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 1:   //正常
                    break;
                case -1:
                    MessageBox.Show("相片解码错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -2:
                    MessageBox.Show("wlt文件后缀错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -3:
                    MessageBox.Show("wlt文件打开错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -4:
                    MessageBox.Show("wlt文件格式错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -5:
                    MessageBox.Show("软件未授权!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -6:
                    MessageBox.Show("设备连接错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
            }
            //如果照片解析成功,则将照片,将从wz.txt中的内容赋值给二进制的bt
            iRet = DllMoudle.SDT_ClosePort(iPort);
            FileInfo f = new FileInfo("wz.txt");
            FileStream fs = f.OpenRead();
            byte[] bt = new byte[fs.Length];
            fs.Read(bt, 0, (int)fs.Length);
            fs.Close();
 
            //然后根据位数分割,获取到相应的值,前30为是姓名,31-32是性别的编码。等等依次类推
            objEDZ.Name = System.Text.UnicodeEncoding.Unicode.GetString(bt, 0, 30).Trim();
            objEDZ.Sex_Code = System.Text.UnicodeEncoding.Unicode.GetString(bt, 30, 2).Trim();
            objEDZ.NATION_Code = System.Text.UnicodeEncoding.Unicode.GetString(bt, 32, 4).Trim();
            string strBird = System.Text.UnicodeEncoding.Unicode.GetString(bt, 36, 16).Trim();
            objEDZ.BIRTH = Convert.ToDateTime(strBird.Substring(0, 4) + "年" + strBird.Substring(4, 2) + "月" + strBird.Substring(6) + "日");
            objEDZ.ADDRESS = System.Text.UnicodeEncoding.Unicode.GetString(bt, 52, 70).Trim();
            objEDZ.IDC = System.Text.UnicodeEncoding.Unicode.GetString(bt, 122, 36).Trim();
            objEDZ.REGORG = System.Text.UnicodeEncoding.Unicode.GetString(bt, 158, 30).Trim();
            string strTem = System.Text.UnicodeEncoding.Unicode.GetString(bt, 188, bt.GetLength(0) - 188).Trim();
            objEDZ.STARTDATE = Convert.ToDateTime(strTem.Substring(0, 4) + "年" + strTem.Substring(4, 2) + "月" + strTem.Substring(6, 2) + "日");
            strTem = strTem.Substring(8);
            if (strTem.Trim() != "长期")
            {
                objEDZ.ENDDATE = Convert.ToDateTime(strTem.Substring(0, 4) + "年" + strTem.Substring(4, 2) + "月" + strTem.Substring(6, 2) + "日");
            }
            else
            {
                objEDZ.ENDDATE = DateTime.MaxValue;
            }

            //找到zp.bmp照片
            objFile = new FileInfo("zp.bmp");
            //若找存在,则将照片通过文件流中督考imgbyte的二进制中,然后用Memorystream流中创建图片Image,
             //放到身份证的Image照片上;而imgbyte则放到照片的二进制中。最后将图片和memorystream都摧毁。
            if (objFile.Exists)
            {
                FileStream fss = new FileStream("zp.bmp", FileMode.Open);
                byte[] imgbyte = new byte[(int)objFile.Length];
                fss.Read(imgbyte, 0, (int)objFile.Length);
                fss.Close();
                MemoryStream ms = new MemoryStream(imgbyte);
                Image img = Image.FromStream(ms);
                objEDZ.PIC_Image = (Image)img.Clone();
                objEDZ.PIC_Byte = imgbyte;
                img.Dispose();
                ms.Dispose();
            }

            //最后界面显示值和照片
            textBox1.Text = textBox1.Text +  objEDZ.Name+objEDZ.Sex_Code + objEDZ.NATION_Code +  objEDZ.BIRTH + objEDZ.ADDRESS + objEDZ.IDC + objEDZ.REGORG + objEDZ.STARTDATE  +  objEDZ.ENDDATE;
            pictureBox1.Image = objEDZ.PIC_Image;
                
        }

        /// <summary>
        /// 关闭端口
        /// </summary>
        /// <param name="iPort">端口号</param>
        /// <param name="iIfOpen">是否开启</param>
        private void closePort(int iPort,int iIfOpen) {
            if (iIfOpen == 0)
            {
                DllMoudle.SDT_ClosePort(iPort);
            }
        }
 }
    以上就是读取身份证的简单版的代码,基本核心就是这些。其中由于我知道我们用的直接是usb口,所以iPort直接写的是1001,如果不知道的情况下,就需要做循环,将1-161001-1016都循环个遍,才行。并且对于iIfOpen是否自动开启端口,我没体会出这个的作用。


  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
大华读取身份证sdk是一种可以用于读取身份证信息的软件开发工具包。通过对接大华读取身份证sdk,我们可以实现在应用程序中读取用户身份证上的信息,例如姓名、性别、民族、出生日期、住址等。 对接大华读取身份证sdk的过程主要涉及以下几个步骤: 1. 下载和安装:首先需要在开发环境中下载和安装大华读取身份证sdk。下载完成后,将sdk集成到开发工具中。 2. SDK配置:在项目中进行相关配置。根据具体的开发工具,需要在项目设置中添加sdk的引用,以便可以在代码中调用sdk提供的接口。 3. 身份证读取:通过调用sdk提供的接口,可以实现身份证读取的功能。在用户放置身份证到读卡器上后,通过调用相应的接口,可以获取身份证上的信息。 4. 数据处理:获取到身份证信息后,可以进行相应的数据处理。例如,可以将信息存储到数据库中,也可以在界面上进行展示或进一步的业务逻辑处理。 5. 异常处理:在进行身份证读取过程中,可能会出现各种异常情况,例如读卡器连接异常、身份证读取失败等。需要在代码中进行相应的异常处理,确保程序的稳定运行。 通过对接大华读取身份证sdk,我们可以方便地实现身份证读取功能,提高用户在应用程序中的使用体验。同时,可以根据实际需求,进行二次开发和定制,以满足特定的业务需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值