摘 要:通过对指纹识别技术的简介,和指纹识别一般的通用接口介绍。我们实现了对指纹识别接口API的基本功能的二次开发,并给出了相应的代码。
一、引言
我们手掌及其手指、脚、脚趾内侧表面的皮肤凸凹不平产生的纹路会形成各种各样的图案。这些纹路的存在增加了皮肤表面的摩擦力,使得我们能够用手来抓起重物。人们也注意到,包括指纹在内的这些皮肤的纹路在图案、断点和交叉点上各不相同,也就是说,是唯一的。依靠这种唯一性,我们就可以把一个人同他的指纹对应起来,通过比较他的指纹和预先保存的指纹进行比较,就可以验证他的真实身份。这种依靠人体的身体特征来进行身份验证的技术称为生物识别技术,指纹识别是生物识别技术的一种。
基于指纹的身份鉴别系统是典型的模式识别系统。它包含两个主要的模块:采集模块和鉴别模块(鉴定或识别)。采集模块采集指纹数据,提取代表这些数据的特征,将特征和相关的身份信息存入数据库;鉴别模块采集待识别样本的生物统计数据,提取特征,然后在数据库中根据提取的特征进行检索,找到最佳匹配(鉴定模式)或者根据用户所宣称的身份,从数据库中调出相应的特征,决定它们是否匹配。
指纹识别应用的基本场所:
l 可以采用指纹进行Windows系统的安全登录(包括本机、局域网和网域登录),指纹屏幕保护,锁定Windows系统等等。
l 指纹认证,直观可靠。可以免去密码带来的烦恼,大大方便用户的使用。
l 可以对电脑中数据文件采取安全的保护措施:只有合法指纹才能打开被保护的文件,而且其中的文件已经用隐含在设备中的密钥加密。被保护的文件即使被非法打开和使用,也无法破解内容。
l 密钥脱机保存,须经指纹验证才能启用。本产品的安全性较之同类产品,有突破性的提高。
指纹产品的二次开发,一般都有以下几个基本接口提供给用户:
1、 端口初始化,设备初始化。
2、 获取用户指纹模板,存储用户指纹模板,验证用户指纹。
3、 设置口令,验证口令,密钥的存取。(附加功能)。
通过对其API的开发,可以使指纹识别技术,很好的结合在我们的应用程序里。极大的提高了程序操作的安全性,简便性。
下面我们就几个通用的功能函数进行简要介绍:
二、主要函数介绍
1、通讯端口的初始化 OpenDevice()
函数原型:BOOL OpenDevice(BOOL bUsbDevice,int COMX)
参数说明:bUsbDevice=1,采用USB通讯;bUsbDevice=0采用COM口通讯。
COMX为COM的串口号。当bUsbDevice=1时,COMX=0;
返回说明:成功返回为非0,失败返回0;
功能说明:打开通讯端口。
2、 指纹的录入与具体操作
GetMB (BYTE* pFpMB, int* pMBLen, HWND hMsgWnd, int nMsgFPID,int nMsgStateID,int nMsgPressOKID);
参数说明: pFpMB 指纹模板数据。
PMBLen 指纹模板数据长度。
HMsgWnd 消息回传句柄。
NMsgFPID 回传手指按下的消息ID。
NMsgStateID 回传指纹录入状态的消息ID。
nMsgPressOKID 回传指纹录入完成手指可以拿开的消息ID。
功能说明:
获取用户的指纹模板数据,共需采集用户的指纹信息3次,保证数据的准确性,int nMsgFPID,int nMsgStateID,int nMsgPressOKI这三个参数在应用中有重要作用:回传不同消息来对用户输入指纹数据状态的判断。
GetTZ (BYTE* pFpTZ, int* pTZLen, HWND hMsgWnd, int nMsgFPID,int nMsgPressOKID);
参数说明:
同上。
功能说明:
获取用户的指纹特征数据,它只采集一次,这也是同GETMB的唯一区别,在获取模板时,为保证数据的准确性,采集三次,在获取特征数据进行比对时,只采集一次。所以在参数中少了nMsgStateID。
MatchTZMB1(BYTE* pFpTZ, int nTZLen, BYTE* pFpMB, int nMBLen);
参数说明:
pFpTZ:指纹特征数据,nTZLen:指纹特征数据长度。 PFpMB:指纹模板数据。NMBLen:
指纹模板数据长度。
功能说明:
对获取的特征数据同已经存在的用户模板数据进行比对。
UserFind1 (char* strUserName)
查找用户。
StoreMB1(BYTE* pFpMB, int nMBLen, char* strUserName);
存储用户模板数据和用户名称。
注意事项:
l NMsgFPID是每次用户在指纹识别仪上按下手指回传的消息。参数LPARAM是返回状态的地址。可以用int Nfpstat=(int*)lparam 来获得结果。
l NmsgStateID是提醒用户按第二、第三次指纹的消息,总共回传两次,第一次回传的意义:
第一次指纹录入成功,提醒用户按第二次指纹。
第二次回传的意义:
第二次指纹录入成功,提醒用户按第三次指纹。第三次指纹的录入状态通过最后的nMsgPressOKID结果包返回。
指纹识别仪为确保采集用户指纹的准确性、唯一性,一般要求用户按三次指纹。
三、指纹识别的几个主要功能的实现过程
主要在于对其函数回传消息的处理和实现。
首先我们要定义用户消息:
#define nMsgFPID WM_USER+1
#define nMsgStateID WM_USER+2
#define nMsgPressOKID WM_USER+3
对这几个消息的处理是应用程序开发的关键,
然后进行消息映射:
ON_MESSAGE(nMsgFPID,nMsgFPIDF)
ON_MESSAGE(nMsgStateID,nMsgstateIDF)
ON_MESSAGE(nMsgPressOKID,nMsgpressokIDF)
下面我们给出实现具体功能函数的示例代码:
BYTE MB[FPMBMAXLEN];
BYTE TZ[FPMBMAXLEN];
char UserName[22];
int MBLen,TZLen;
//获取用户模板数据
void CFpTestDlg::OnGetMB()
{
if (GetMB(MB, &MBLen, hMsgWnd, nMsgFPID,nMsgStateID,nMsgPressOKID)!=FPOK)
AfxMessageBox("提取指纹模板出错");
else
AfxMessageBox("提取指纹模板成功");
this->SetDlgItemInt(IDC_EDIT2,MBLen);
}
//获取用户特征数据
void CFpTestDlg::OnGetTZ()
{
if (GetTZ(TZ, &TZLen, 0, 0, 0)!=FPOK)
AfxMessageBox("提取指纹特征出错");
else
AfxMessageBox("提取指纹特征完成");
this->SetDlgItemInt(IDC_EDIT3,TZLen);
}
//对用户模板数据和用户特征数据进行比对,确定是否登陆管理系统
void CFpTestDlg::OnVerify()
{
if (MatchTZMB(TZ, TZLen, MB, MBLen)!=FPOK)
AfxMessageBox("比对失败,请重新输入指纹或退出");
else
AfxMessageBox("比对成功,请进入管理系统");
//分配权限,进入具体系统
}
//存储用户模板数据
void CFpTestDlg::OnStoreMB()
{
UpdateData(TRUE);
strcpy(UserName, m_strUserName);
if (StoreMB(MB,MBLen, UserName)!=FPOK)
AfxMessageBox("存储失败");
else
AfxMessageBox("存储成功");
}
//查找指定用户
void CFpTestDlg::OnFindUser()
{
if (UserFind(UserName)!=FPOK)
AfxMessageBox("未找到用户");
else
{
m_strUserName = UserName;
UpdateData(FALSE);
AfxMessageBox("找到用户");
}
}
//初始化端口
void CFpTestDlg::OnButton1()
{
CWnd * pwnd=GetForegroundWindow();
hMsgWnd=pwnd->GetSafeHwnd();
// TODO: Add your control notification handler code here
//if (CloseDevice())
//if (Summary(10))
bool busb=1;
int comx=0;
OpenDevice(busb,comx);
MessageBox("测试开始");
}
//回传消息处理,包括:nMsgFPIDF,nMsgstateIDF,nMsgpressokIDF。
void CFpTestDlg::nMsgFPIDF(WPARAM wparam,LPARAM lparam)
{
// this->SetDlgItemInt(IDC_EDIT1,lparam);
int *nfpstat=(int*)lparam;
i=i++;
this->SetDlgItemInt(IDC_EDIT1,i);
if (*nfpstat==0x2222)
{
MessageBox("按下手指成功,回传消息!!");
}
else
{
MessageBox("按下手指不成功,回传消息!!");
}
//return 1;
//MessageBox(" nMsgFPIDF() ok");
}
//这是提醒用户按第二、三次指纹,回传的消息处理函数
LRESULT CFpTestDlg::nMsgstateIDF(WPARAM wparam,LPARAM lparam)
{
int *nstat=(int*)lparam;
//this->SetDlgItemInt(IDC_EDIT2,*nstat);
if(*nstat==0x4444)
{
MessageBox("这次指纹按成功,请再按");
}
else
{
MessageBox("这次指纹按不成功,请再按");
}
return 1;
}
//这是提醒用户指纹录入完成的消息处理函数
LRESULT CFpTestDlg::nMsgpressokIDF(WPARAM wparam,LPARAM lparam)
{
int *nstatok=(int*)lparam;
//this->SetDlgItemInt(IDC_EDIT3,*nstatok);
if(*nstatok==0x3333)
{
MessageBox("指纹模板录入成功,谢谢");
}
else
{
MessageBox("指纹模板录入不成功。请重录。");
}
return 1;
}
四、结束语
二次开发过程的难点在于对回传消息的理解和处理。通过对示例代码函数的修改应用,可以很快的无缝的集成到具体应用程序中去,为应用程序的安全加了一道防盗门。
|