华视100UC 身份证阅读器 Java

  • 哪位大佬有64位可用的dll文件,施舍给小弟吧,万分感谢
    • 功能
    • 环境
    • 个人想法(有不对的地方希望大佬指正)
    • 对于dll文件的想法
    • 目录结构
    • 1. pom.xml
    • 2. 拷贝dll文件到resources
    • 3. 接口映射Termb.dll中的方法
    • 4. 调用接口中的方法
    • 5. 连接、认证、获取信息、关闭 阅读器

哪位大佬有64位可用的dll文件,施舍给小弟吧,万分感谢

功能

读取身份证上的数据,将照片保存到指定路径

环境

  1. jdk1.8 32位
  2. window 11
  3. Maven
  4. 乱找的dll,找了一堆,终于发现可以用的了。官方开发包的dll只能读出信息,读不出图片,求赐教

个人想法(有不对的地方希望大佬指正)

  1. 所有阅读器采用的是相同的内部硬件,厂商只是套了个外壳
  2. 代码看上去很多,大部分都是类似的方法,如果只获取身份证其中一项信息,代码会很少
  3. 官方下载的说明文档里说只要调用接口中CVR_Read_ContentCVR_Read_FPContent方法就可以在对应的位置生成两个文件一个是txt文档记录身份证上的信息,一个是bmp身份证图片,这套dll只能生成在默认的路径C:\Users\用户\AppData\Local\Temp\chinaidcard
  4. 用官方提供的开发包,死活弄不出图片,在网上找了其他的安装包,把下图中3个dll文件复制到程序中,居然能用了。jdk64位的还是弄不出图片。
  5. 要不是我水平差,要不就是华视故意的,官网提供的dll文件居然不能用,如果是故意的那这公司可真的恶心。
  6. 感觉Termb和WltRS这两个dll文件是配套的,换其中一个,程序可能就跑不起来。

对于dll文件的想法

  1. 目前网上可以找到的读取身份证信息的程序都是用的32位dll,没找到64位的dll。
  2. 使用官方开发包内的64位dll可以读取身份证的信息,就是无法读取图片。感觉还是dll的事情,找了两天也没找到可用的。无论问哪儿要开发包,客服都要让我提供购买的订单号,上级单位发下来的设备,我去哪儿要订单号。
  3. 对华视公司的看法,小气、没格局。要个最新的开发包非要个订单号,给产品照片都不行,产品的开发包也藏着掖着,官网提供的开发包里面写的是乱七八糟,特指java的demo,其他语言我看不懂。既然想卖产品那应该是应用的越广泛卖的越好,别人用你的设备做更广泛的应用,设备就能卖的更多,所以要你开发包,你应该高兴才对。看看自己做的程序,做了十几年了,界面还是难看的要死。

目录结构

1. pom.xml

依赖

    <dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>5.11.0</version></dependency>

2. 拷贝dll文件到resources

下载

3. 接口映射Termb.dll中的方法

使用jna连接dll文件,接口中所有方法都是Termb中的方法

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;public interface CardLibrary extends Library {// 参数1:只写名称,不写后缀,符合jni规范,可跨平台操作,linux中后缀为soCardLibrary INSTANCE = Native.load("Termb", CardLibrary.class);/*** 本函数用于PC与华视电子第二代居民身份证阅读器的连接* @param Port 连接串口(COM1~COM16)或USB口(1001~1016)* @return 1 正确 2 端口打开失败 0 动态库加载失败*/int CVR_InitComm(int Port);/*** 本函数用于关闭PC到阅读器的连接。* @return 1 正确 0 错误*/int CVR_CloseComm();/*** 本函数用于读卡器和卡片之间的合法身份确认。卡认证循环间隔大于300ms。 若卡片放置后发生认证错误时,应移走卡片重新放置。* @return 1 正确 卡片认证成功 2 错误 寻卡失败 3 错误 选卡失败 0 错误 初始化失败*/int CVR_Authenticate();/*** 本函数用于通过阅读器从第二代居民身份证中读取相应信息。卡认证成功以后才可做读卡操作, 读卡完毕若继续读卡应移走二代证卡片重新放置做卡认证。* 读卡成功后在termb.dll文件所在路径下生成wz.txt(文字信息)和zp.bmp(照片信息) wz.txt内容示例如下: 张红叶 女 汉* 1988-11-18 河北省邯郸市临漳县称勾镇称勾东村复兴路25号 130423198811184328 临漳县公安局* 2011.03.30-2021.03.30 读各项文字信息到自定义内存缓冲* @param active 兼容以前版本,无实际意义, 1 读取基本信息,2 只读文字信息 ,3 只读最新住址信息,5 芯片管理* @return 1 正确 0 错误 99 异常*/int CVR_Read_Content(int active);/*** 与 int CVR_Read_Content(int active);平级* 本函数用于通过阅读器从第二代居民身份证中读取相应信息。卡认证成功以后才可做读卡操作,读卡完毕若继续读卡应移走二代证卡片重新放置做卡认证。* 参数: 无** */int CVR_Read_FPContent();/*** 获取各种信息* */int  GetPeopleName(byte[] strTmp, byte[] strLen);int  GetPeopleSex(byte[] strTmp, byte[] strLen);int  GetPeopleNation(byte[] strTmp, byte[] strLen);int  GetPeopleBirthday(byte[] strTmp, byte[] strLen);int  GetPeopleAddress(byte[] strTmp, byte[] strLen);int  GetPeopleIDCode(byte[] strTmp, byte[] strLen);int  GetDepartment(byte[] strTmp, byte[] strLen);int  GetStartDate(byte[] strTmp, byte[] strLen);int  GetEndDate(byte[] strTmp, byte[] strLen);int  GetBMPData(byte[] strTmp, IntByReference strLen);int  GetJpgData(byte[] strTmp, IntByReference strLen);int  CVR_GetSAMID(byte[] strTmp, byte[] strLen);
}

4. 调用接口中的方法

import com.sun.jna.ptr.IntByReference;
import java.io.FileOutputStream;/*** a参数在说明文档中确定了最大的长度* b参数是C++的int类型长度为4个字节* 方法中a参数返回查询到的值,b参数返回a的长度* java中数组在创建时就需要确定好长度,所以b参数没有意义* */
public class Card {/*** 得到姓名信息* @return 姓名信息* @throws Exception*/public static String GetPeopleName() throws Exception {try {byte[] a = new byte[30];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetPeopleName(a, b) == 1 ? new String(a,"gb2312").trim() : "";} catch (Exception ex) {ex.printStackTrace();}return "";}/*** 得到性别信息* @return 性别信息* @throws Exception*/public static String GetPeopleSex() throws Exception {try {byte[] a = new byte[2];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetPeopleSex(a, b) == 1 ? new String(a,"gb2312").trim() : "";} catch (Exception ex) {ex.printStackTrace();}return "";}/*** 得到民族信息* @return 民族信息* @throws Exception*/public static String GetPeopleNation() throws Exception {try {byte[] a = new byte[20];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetPeopleNation(a, b) == 1 ? new String(a,"gb2312").trim() : "";} catch (Exception ex) {ex.printStackTrace();}return "";}/*** 得到出生日期信息* @return 到出生日期信息* @throws Exception*/public static String GetPeopleBirthday() throws Exception {try{byte[] a = new byte[16];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetPeopleBirthday(a,b) == 1 ?  new String(a).trim() :  "";}catch(Exception ex){ex.printStackTrace();}return "";}/*** 得到地址信息* @return 地址信息* @throws Exception*/public static String GetPeopleAddress() throws Exception {try{byte[] a = new byte[70];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetPeopleAddress(a,b) == 1 ?  new String(a,"gb2312").trim() :  "";}catch(Exception ex){ex.printStackTrace();}return "";}/*** 得到卡号信息* @return 卡号信息* @throws Exception*/public static String GetPeopleIDCode() throws Exception {try{byte[] a = new byte[36];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetPeopleIDCode(a,b) == 1 ?  new String(a).trim() :  "";}catch(Exception ex){ex.printStackTrace();}return "";}/*** 得到发证机关信息* @return 发证机关信息* @throws Exception*/public static String GetDepartment() throws Exception {try{byte[] a = new byte[30];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetDepartment(a,b) == 1 ?  new String(a,"gb2312").trim() :  "";}catch(Exception ex){ex.printStackTrace();}return "";}/*** 得到有效开始日期* @return 有效开始日期* @throws Exception*/public static String GetStartDate() throws Exception {try{byte[] a = new byte[16];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetStartDate(a,b) == 1 ?  new String(a,"gb2312").trim() :  "";}catch(Exception ex){ex.printStackTrace();}return "";}/*** 得到有效截止日期* @return 有效截止日期* @throws Exception*/public static String GetEndDate() throws Exception {try{byte[] a = new byte[16];byte[] b = new byte[4];return CardLibrary.INSTANCE.GetEndDate(a,b) == 1 ?  new String(a,"gb2312").trim() :  "";}catch(Exception ex){ex.printStackTrace();}return "";}/*** 得到安全模块号码* @return 安全模块号码* @throws Exception*/public static String CVR_GetSAMID() throws Exception {try{byte[] a = new byte[4*10];byte[] b = new byte[4];return CardLibrary.INSTANCE.CVR_GetSAMID(a,b) == 1 ?  new String(a).trim() :  "";}catch(Exception ex){ex.printStackTrace();}return "";}/*** 获取照片,将图片写到指定路径* @return 获取成功 boolean* @throws Exception*/public static boolean GetBMPData() throws Exception {try{byte[] a = new byte[38862];IntByReference len = new IntByReference();FileOutputStream fos = new FileOutputStream("D:\\123.bmp");if (CardLibrary.INSTANCE.GetBMPData(a,len) == 1){fos.write(a,0,len.getValue());fos.flush();fos.close();return true;}else return false;}catch(Exception ex){ex.printStackTrace();}return false;}/*** 获取照片,将图片写到指定路径* @return 获取成功 boolean* @throws Exception*/public static boolean GetJpgData() throws Exception {try{ // 返回固定的38862字节,使用看图软件另存后5000字节左右,// 说明文档中没有明确说明返回的字节数。byte[] a = new byte[38862];IntByReference len = new IntByReference();FileOutputStream fos = new FileOutputStream("D:\\123.jpg");if (CardLibrary.INSTANCE.GetJpgData(a,len) == 1){System.out.println("len = " + len);fos.write(a,0,len.getValue());fos.flush();fos.close();return true;}else return false;}catch(Exception ex){ex.printStackTrace();}return false;}
}

5. 连接、认证、获取信息、关闭 阅读器

public class CardMain {public static void main(String[] args) {// 测试所有端口,打开连接int init = 0;for (int i = 1001; i < 1016; i++) {init = CardLibrary.INSTANCE.CVR_InitComm(i);if(init == 1) {System.out.println("初始化硬件成功");break;}}// 验证初始化信息if (init != 1) {System.out.println("初始化硬件失败");return;}// 卡认证int auth = 0;while (true) {auth = CardLibrary.INSTANCE.CVR_Authenticate();if (auth == 1){System.out.println("读卡器和卡片之间的合法身份确认:身份认证成功");}if (auth != 1) {System.out.println("读卡器和卡片之间的合法身份确认:身份认证失败");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}} else {break;}}// 读取卡信息,认证成功后文本信息和照片的默认保存路径//C:\Users\用户\AppData\Local\Temp\chinaidcardint read = CardLibrary.INSTANCE.CVR_Read_Content(1); //默认路径文件:config.ini fp.dat wz.txt xp.bmp xp.jpg zp.bmp xp.wlt// 使用手册上说:执行后会在运行目录下生成以下文件信息。使用这套dll还是会生成到默认路径
//      int read = CardLibrary.INSTANCE.CVR_Read_FPContent();      //默认路径文件:config.ini fp.dat wz.txt xp.bmp xp.jpg zp.bmpif (read != 1) {System.out.println("获取信息失败");} else {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("成功获取信息");try {System.err.println(Card.GetPeopleName());System.err.println(Card.GetPeopleSex());System.err.println(Card.GetPeopleNation());System.err.println(Card.GetPeopleBirthday());System.err.println(Card.GetPeopleAddress());System.err.println(Card.GetPeopleIDCode());System.err.println(Card.GetDepartment());System.err.println(Card.GetStartDate());System.err.println(Card.GetEndDate());System.err.println(Card.CVR_GetSAMID());if (Card.GetBMPData())System.err.println("bmp图片获取成功");if (Card.GetJpgData())System.err.println("jpg图片获取成功");} catch (Exception e) {e.printStackTrace();}}int i = CardLibrary.INSTANCE.CVR_CloseComm();if (i == 1){System.out.println("关闭连接成功");}}
}

华视100UC 身份证阅读器 Java相关推荐

  1. vue调用华视电子身份证阅读器cvr-100uc

    1.去官网下载安装包服务下载_华视电子 解压后点击 安装后找到网页版开发包 点击华视电子读卡器安装,安装后点击读卡服务 安装USB插件. 2.新建reader.js文件,阅读器默认端口19196 3. ...

  2. 使用jnative调用c语言动态库对接华视电子身份证阅读机

    一 身份证阅读器SDK使用手册 1. 定义 应用函数开发包含下列文件: termb.dll API函数的动态联接库 sdtapi.dll 安全模块通讯函数 UnPack.dll 身份证相片解码库 适用 ...

  3. 使用jna调用c语言动态库对接华视电子身份证阅读机

    一些C语言的接口见上一篇文章 同样把用到的动态库放到jdk的bin目录文件夹下 Termb.java import com.sun.jna.Library; import com.sun.jna.Na ...

  4. JNA二次开发华视身份证阅读器

    JNA二次开发华视身份证阅读器 前言 添加依赖 SDK资料 编写代码 遇到的问题(坑) 前言 这两天了解了一下java调用dll动态库的方法,总的有三种:JNI.JNA.JNative,其中JNA调用 ...

  5. Kotlin之身份证阅读器(华视)二次开发

    一.简介 身份证阅读器使用场景比较多,围绕它按照自己的需求进行二次开发的也不少,我这次也是围绕身份证阅读器进行二次开发,不过使用的是kotlin作为开发的语言,资料比较少,参考了java的开发设计JA ...

  6. python能调用身份证读卡器吗_最近的项目中用到读卡器,用的华视身份证阅读器,附上SDK使用手册...

    最近的项目中用到读卡器,用的华视身份证阅读器,附上SDK使用手册 1.定义 应用函数开发包含下列文件: termb.dll      API函数的动态联接库 sdtapi.dll     内部动态库 ...

  7. VUE实现华视身份证阅读器读取身份证信息

    VUE实现华视身份证阅读器读取身份证信息 话不多上直接上代码,写的不怎么规范多多包涵,我是在模态框实现的,在这里就只提供模态框代码. 最后附上华视身份证阅读器安装文件和浏览器插件链接: [https: ...

  8. 华视身份证阅读器SDK使用手册

    华视身份证阅读器SDK使用手册 V1.33 华视电子读写设备有限公司  2008年07月11日 概述 本手册是操作身份证阅读器动态库应用函数的定义格式.调用方法和返回值的说明.在使用前,请确认授权文件 ...

  9. VUE实现华视身份证阅读器读取身份证信息(本文分两种情况,第一中是点击按钮读取信息,一种是自动读取信息)

    本文是用了vue+element来实现华视身份证读卡器读取身份信息的,当然在开发之前要做好前提准备,就是厂家提供对应设备的api和安装对应的驱动.本文通过两种方法来实现读取信息,第一种是点击按钮读取信 ...

最新文章

  1. debian卸载php_在Debian10上安装PHP的方法
  2. 用友致远协同OA办公软件可以给外驻领导带来什么好处?
  3. python建模仿真 matlab_清华大学出版社-图书详情-《仿真建模与MATLAB实用教程》
  4. P1040 加分二叉树【dp+深搜】
  5. 工作中的第一份LoadRunner脚本
  6. Markdown的常用使用语法
  7. Spring(三)之自动装配、表达式
  8. JavaWeb:Maven
  9. CVPR2022论文列表(中英对照)
  10. 在Excel中批量生成送货单,按数据类别批量生成产品标签
  11. 基于单片机的电子秤(数码管)系统设计(#0416)
  12. 主板检测卡c5_主板检测卡代码大全
  13. 张正友相机标定全解析
  14. winen中文_enWin使用部分中文字库
  15. 网络安全证书已过期或不可信怎么办
  16. JAVA创建一个Box类(长方体),在Box类中定义三个变量,分别表示长方体的长(length)、宽(width)和高(heigth)
  17. Educoder Java高级特性 - JDBC(上)
  18. 什么是子网掩码,如何判断两个IP是不是同一网段
  19. 划重点了!2021软考网工考试范围重点圈定!
  20. 深入理解苹果系统(Unicode)字符串的排序方法

热门文章

  1. 合并字符串(c++)
  2. java switch finally_java switch语句详解
  3. cannot find -lxxx 问题的总结
  4. 公式编译器AxMath安装包及在word中使用的教程
  5. 8个质量极高的资源网站,建议低调使用
  6. Chrome 录屏神器 Screenity
  7. 烟台大学计算机学院王文学,杨玉军-烟台大学 数学与信息科学学院
  8. python生存曲线_知识分享 | 生存分析: 在 Python 中的实现(下篇)
  9. [转]数据挖掘十大经典算法
  10. Android版股票K线图实现方案