一 身份证阅读器SDK使用手册
1. 定义
应用函数开发包含下列文件: termb.dll API函数的动态联接库 sdtapi.dll 安全模块通讯函数 UnPack.dll 身份证相片解码库 适用操作系统: Windows NT: 需要NT 3.1版或以后版本 Windows: 需要 Windows 98、Windows 2000或以后版本 适用开发语言: Visual C 5.0 及以后版本 Visual Basic 5.0 及以后版本 Delphi 3.0 及以后版本 PowerBuilder 6.0 及以后版本
2. 函数列表
//以下为主要API函数 int CVR_InitComm(int Port) 初始化连接; int CVR_Authenticate() 卡认证; int CVR_Read_Content(int active) 读卡操作。 int CVR_CloseComm() 关闭连接;
//以下为可选API函数,方便二次开发 int GetPeopleName(char *strTmp, int *strLen) 得到姓名信息 int GetPeopleSex(char *strTmp, int *strLen) 得到性别信息 int GetPeopleNation(char *strTmp, int *strLen) 得到民族信息 int GetPeopleBirthday(char *strTmp, int *strLen) 得到出生日期 int GetPeopleAddress(char *strTmp, int *strLen) 得到地址信息 int GetPeopleIDCode(char *strTmp, int *strLen) 得到身份证号信息 int GetDepartment(char *strTmp, int *strLen) 得到发证机关信息 int GetStartDate(char *strTmp, int *strLen) 得到有效开始日期 int GetEndDate(char *strTmp, int *strLen) 得到有效截止日期 int CVR_GetSAMID(char *SAMID) 得到安全模块号
3. 函数说明
初始化连接
原 型:int CVR_InitComm (int Port) 说 明:本函数用于PC与华视电子第二代居民身份证阅读器的连接。 参 数:Port:连接串口(COM1COM16)或USB口(10011016) 值 意义 1 串口1 2 串口2 3 串口3 4 串口4 1001 USB口1 1002 USB口2 1003 USB口3 1004 USB口4
返 回 值: 值 意义 1 正确 2 端口打开失败 0 动态库加载失败
关闭串口
原 型: int CVR_CloseComm(void) 说 明:本函数用于关闭PC到阅读器的连接。 参 数:无 返 回 值: 值 意义 1 正确 0 错误
卡认证
原 型:int CVR_Authenticate (void) 说 明:本函数用于读卡器和卡片之间的合法身份确认。卡认证循环间隔大于300ms。 参 数: 返 回 值: 值 意义 说明 1 正确 卡片认证成功 2 错误 寻卡失败 3 错误 选卡失败 0 错误 初始化失败 注意:若卡片放置后发生认证错误时,应移走卡片重新放置。
读卡操作
原 型:int CVR_Read_Content(int active); 说 明:本函数用于通过阅读器从第二代居民身份证中读取相应信息。卡认证成功以后才可做读卡操作,读卡完毕若继续读卡应移走二代证卡片重新放置做卡认证。 参 数:active:兼容以前版本,无实际意义
返 回 值: 返回值 意义 1 正确 0 错误 99 异常 说明: 读卡成功后在termb.dll文件所在路径下生成wz.txt(文字信息)和zp.bmp(照片信息) wz.txt内容示例如下: 张红叶 女 汉 1988-11-18 河北省邯郸市临漳县称勾镇称勾东村复兴路25号 130423198811184328 临漳县公安局 2011.03.30-2021.03.30
读各项文字信息到自定义内存缓冲
原 型: int GetPeopleName(char *strTmp, int *strLen) //得到姓名信息 int GetPeopleSex(char *strTmp, int *strLen) //得到性别信息 int GetPeopleNation(char *strTmp, int *strLen) //得到民族信息 int GetPeopleBirthday(char *strTmp, int *strLen) //得到出生日期 int GetPeopleAddress(char *strTmp, int *strLen) //得到地址信息 int GetPeopleIDCode(char *strTmp, int *strLen) //得到卡号信息 int GetDepartment(char *strTmp, int *strLen) //得到发证机关信息 int GetStartDate(char *strTmp, int *strLen) //得到有效开始日期 int GetEndDate(char *strTmp, int *strLen) //得到有效截止日期 int CVR_GetSAMID(char * SAMID) //得到安全模块号码 参数: *strTmp 返回的信息缓存指针。 *strLen 返回的信息长度指针。 返 回 值: 返回值 意义 1 正确 0 错误
注意:若采用查询方式自动判断卡片是否放置,则间隔时间建议大于300ms。
二 开始对接
主要做的功能就是使用身份证刷卡登录系统
大致流程是这样的: 前端是定时请求后台 后台流程就是
- 初始化连接
- 卡认证
- 读卡操作
- 得到身份证号信息
然后拿到这个身份证号后与数据库的用户对应身份证对比一下 如果相同 就调转到主页 完成登录
jnative 使用套路的话就是把用到的dll文件放到jdk的bin目录下面
动态链接库编译时选择的平台。如果通过x86平台编译,那么只能使用32位jdk环境加载,如果要使用64位jdk,必须使用x64平台编译。
那么怎么看dll文件是32位还是64位呢 可以装一个Visual Studio 自带工具dumpbin.exe 执行dumpbin.exe /headers 文件路径 像这样:
jnative 用法:
代码语言:javascript复制JNative n = null;
try
{
n = new JNative("Termb.dll", "CVR_InitComm");
n.setRetVal(Type.INT); // 指定返回参数的类型
n.setParameter(0, Port);//设置参数
n.invoke(); // 调用方法
return Integer.parseInt(n.getRetVal());//得到返回值
}
finally
{
}
实例:
引入jar包
代码语言:javascript复制 <dependency>
<groupId>org.apache</groupId>
<artifactId>JNative</artifactId>
<version>1.0.0</version>
</dependency>
后台代码:
代码语言:javascript复制 //1.打开端口
int portReturnCode =1001;
try
{
portReturnCode = CVR_InitComm(Integer.parseInt(intport));
logger.info("打开端口返回值:" String.valueOf(portReturnCode));
if (portReturnCode!=1) {
return null;
}
}
catch(Exception ex)
{
logger.error("打开端口调用异常!" ex.getMessage());
}
// 2. 认证
int authReturnCode = 0;
try
{
authReturnCode = CVR_Authenticate();
logger.info("认证返回值:" String.valueOf(authReturnCode));
if (authReturnCode!=1) {
return null;
}
}
catch(Exception ex)
{
logger.error("认证调用异常!" ex.getMessage());
}
//3. 读卡
int readReturnCode = 0;
try
{
readReturnCode = CVR_Read_Content(4);
logger.info("读卡返回值:" String.valueOf(readReturnCode));
if (authReturnCode!=1) {
return null;
}
}
catch(Exception ex)
{
logger.error("读卡调用异常!" ex.getMessage());
}
//4. 读取身份证号码
int readIdReturnCode = 0;
try
{
readIdReturnCode = GetPeopleIDCode();
logger.info("读取身份证号码返回值:" String.valueOf(readIdReturnCode));
if(readIdReturnCode == 1)
{
logger.info("身份号码:" strTmp.trim());
}
}
catch(Exception ex)
{
logger.error("调用异常!" ex.getMessage());
}
return strTmp.trim();
}
调用动态库的方法:
代码语言:javascript复制 /**
* 身份证阅读机打开端口
* @param Port
* @return
* @throws NativeException
* @throws IllegalAccessException
* @throws UnsupportedEncodingException
*/
private int CVR_InitComm(int Port) throws NativeException, IllegalAccessException, UnsupportedEncodingException
{
JNative n = null;
try
{
n = new JNative("Termb.dll", "CVR_InitComm");
n.setRetVal(Type.INT); // 指定返回参数的类型
n.setParameter(0, Port);
n.invoke(); // 调用方法
return Integer.parseInt(n.getRetVal());
}
finally
{
}
}
/**
* 身份证阅读机认证
* @return
* @throws NativeException
* @throws IllegalAccessException
*/
private int CVR_Authenticate() throws NativeException, IllegalAccessException
{
JNative n = null;
try
{
n = new JNative("Termb.dll", "CVR_Authenticate");
n.setRetVal(Type.INT); // 指定返回参数的类型
n.invoke(); // 调用方法
return Integer.parseInt(n.getRetVal());
}
finally
{
}
}
/**
* 身份证阅读机读卡
* @return
* @throws NativeException
* @throws IllegalAccessException
*/
private int CVR_Read_Content(int Active) throws NativeException, IllegalAccessException
{
JNative n = null;
try
{
n = new JNative("Termb.dll", "CVR_Read_Content");
n.setRetVal(Type.INT); // 指定返回参数的类型
n.setParameter(0, Active);
n.invoke(); // 调用方法
return Integer.parseInt(n.getRetVal());
}
finally
{
}
}
/**
* 身份证阅读机获取身份证号
* @return
* @throws NativeException
* @throws IllegalAccessException
*/
private int GetPeopleIDCode() throws NativeException, IllegalAccessException
{
JNative n = null;
try
{
n = new JNative("Termb.dll", "GetPeopleIDCode");
n.setRetVal(Type.INT); // 指定返回参数的类型
Pointer a = new Pointer(MemoryBlockFactory.createMemoryBlock(4*10));
Pointer b = new Pointer(MemoryBlockFactory.createMemoryBlock(4*30));
n.setParameter(0,b);
n.setParameter(1,a);
n.invoke();
byte[] by = new byte[120];
by = b.getMemory();
try
{
strTmp = new String(by,"gb2312");
}
catch (UnsupportedEncodingException ex)
{
logger.error("获取身份信息异常:",ex);
}
int asInt = a.getAsInt(0);
a.dispose();
b.dispose();
return Integer.parseInt(n.getRetVal());
}
finally
{
}
}
附上一个demo: https://github.com/xiepanpan/CVR100Demo