一 身份证阅读器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 用法:
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包
<dependency>
<groupId>org.apache</groupId>
<artifactId>JNative</artifactId>
<version>1.0.0</version>
</dependency>
后台代码:
//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();
}
调用动态库的方法:
/**
* 身份证阅读机打开端口
* @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