#ifndef __READ_CARD_INFO_H
#define __READ_CARD_INFO_H
#include <string>
class CardInfo
{
public:
std::wstring name;
std::wstring sex;
std::wstring national;
std::wstring birthData;
std::wstring residenceAddress;
std::wstring identityCardNo;
std::wstring organIssue;
std::wstring validStartDay;
std::wstring validEndDay;
};
class ReadCardInfo
{
public:
ReadCardInfo();
~ReadCardInfo();
std::wstring GetNationName(int number);
bool ReadCard(CardInfo &info);
private:
void InitNationName();
void GetCardInfo(unsigned char *Msg, int MsgLen);
void WltChangeToBmpFile(unsigned char* pphotoMsg, int len);
public:
bool m_bExit;
bool m_bReadCardSucc;
CardInfo m_cardInfo;
private:
int m_commPort;
bool m_bClosePort;
std::wstring m_nationNameVec[100];
};
#endif
#include "stdafx.h"
#include "ReadCardInfo.h"
#include "log.h"
#include "sdtapi.h"
#include "WltRS.h"
ReadCardInfo::ReadCardInfo()
{
m_bExit = false;
m_bClosePort = true;
m_commPort = 1001; // usb口1001
InitNationName();
}
ReadCardInfo::~ReadCardInfo()
{
m_bExit = true;
}
bool ReadCardInfo::ReadCard(CardInfo &info)
{
int ret = -1;
if (m_bClosePort)
{
ret = SDT_OpenPort(m_commPort);
if (ret == 0x90) //打开成功
{
m_bClosePort = false;
}
}
int iIfOpen = 0; //是否需要打开端口
unsigned char pucManaInfo[4] = { 0 }; //证件芯片管理号
ret = SDT_StartFindIDCard(m_commPort, pucManaInfo, iIfOpen);
if (ret != 0x9f)
{
m_bReadCardSucc = false;
return false;
}
unsigned char pucManaMsg[8] = { 0 }; //证件序列号
ret = SDT_SelectIDCard(m_commPort, pucManaMsg, iIfOpen);
if (ret != 0x90)
{
m_bReadCardSucc = false;
WLog(LOG_DEBUG, "SDT_SelectIDCard ret[%x]", ret);
return false;
}
unsigned char pucCHMsg[256] = { 0 }; //文字信息最长256字节
unsigned char pucPHMsg[1024] = { 0 }; //相片信息最长1024字节
unsigned char pucFPMsg[1024] = { 0 }; //指纹信息最长1024字节
unsigned int uiCHMsgLen, uiPHMsgLen, uiFPMsgLen;
ret = SDT_ReadBaseMsg(m_commPort, pucCHMsg, &uiCHMsgLen, pucPHMsg, &uiPHMsgLen, iIfOpen);
if (ret != 0x90)
{
m_bReadCardSucc = false;
WLog(LOG_DEBUG, "SDT_ReadBaseMsg ret[%x]", ret);
return false;
}
GetCardInfo(pucCHMsg, uiCHMsgLen);
WltChangeToBmpFile(pucPHMsg, uiPHMsgLen);
info = m_cardInfo;
return true;
}
void ReadCardInfo::InitNationName()
{
//初始化民族信息字典
m_nationNameVec[1] = L"汉";
m_nationNameVec[2] = L"蒙古";
m_nationNameVec[3] = L"回";
m_nationNameVec[4] = L"藏";
m_nationNameVec[5] = L"维吾尔";
m_nationNameVec[6] = L"苗族";
m_nationNameVec[7] = L"彝";
m_nationNameVec[8] = L"壮";
m_nationNameVec[9] = L"布依";
m_nationNameVec[10] = L"朝鲜";
m_nationNameVec[11] = L"满";
m_nationNameVec[12] = L"侗";
m_nationNameVec[13] = L"瑶";
m_nationNameVec[14] = L"白";
m_nationNameVec[15] = L"土家";
m_nationNameVec[16] = L"哈尼";
m_nationNameVec[17] = L"哈萨克";
m_nationNameVec[18] = L"傣";
m_nationNameVec[19] = L"黎";
m_nationNameVec[20] = L"傈僳";
m_nationNameVec[21] = L"佤";
m_nationNameVec[22] = L"畲";
m_nationNameVec[23] = L"高山";
m_nationNameVec[24] = L"拉祜";
m_nationNameVec[25] = L"水";
m_nationNameVec[26] = L"东乡";
m_nationNameVec[27] = L"纳西";
m_nationNameVec[28] = L"景颇";
m_nationNameVec[29] = L"柯尔克孜";
m_nationNameVec[30] = L"土";
m_nationNameVec[31] = L"达翰尔";
m_nationNameVec[32] = L"仫佬";
m_nationNameVec[33] = L"羌";
m_nationNameVec[34] = L"布朗";
m_nationNameVec[35] = L"撒拉";
m_nationNameVec[36] = L"毛南";
m_nationNameVec[37] = L"仡佬";
m_nationNameVec[38] = L"锡伯";
m_nationNameVec[39] = L"阿昌";
m_nationNameVec[40] = L"普米";
m_nationNameVec[41] = L"塔吉克";
m_nationNameVec[42] = L"怒";
m_nationNameVec[43] = L"乌孜别克";
m_nationNameVec[44] = L"俄罗斯";
m_nationNameVec[45] = L"鄂温克";
m_nationNameVec[46] = L"德昂";
m_nationNameVec[47] = L"保安";
m_nationNameVec[48] = L"裕固";
m_nationNameVec[49] = L"京";
m_nationNameVec[50] = L"塔塔尔";
m_nationNameVec[51] = L"独龙";
m_nationNameVec[52] = L"鄂伦春";
m_nationNameVec[53] = L"赫哲";
m_nationNameVec[54] = L"门巴";
m_nationNameVec[55] = L"珞巴";
m_nationNameVec[56] = L"基诺";
m_nationNameVec[57] = L"其它";
m_nationNameVec[98] = L"外国人入籍";
}
std::wstring ReadCardInfo::GetNationName(int number)
{
return m_nationNameVec[number];
}
void ReadCardInfo::GetCardInfo(unsigned char *msg, int msgLen)
{
//身份证字符串定义
//30字节姓名
//2字节性别
//4字节民族
//16字节生日
//70字节地址
//36字节号码
//30字节发证机关
//32字节有效期
const int fixMsgLen = 30 + 2 + 4 + 16 + 70 + 36 + 30 + 32;
if (msg == NULL || msgLen < fixMsgLen)
{
WLog(LOG_ERR, "Card CHMsg is NULL or msg len[%d] != fixMsgLen[%d]", msgLen, fixMsgLen);
return;
}
m_cardInfo = CardInfo();
wchar_t strTmpMsg[100] = { 0 }; //中文消息必须用宽字符的字符串才能正常显示中文,否则显示为乱码
const char* pStr = (const char*)msg;
memcpy(strTmpMsg, pStr, 30);
pStr += 30;
m_cardInfo.name = std::wstring(strTmpMsg); //名字
memset(strTmpMsg, 0x00, sizeof(strTmpMsg));
memcpy(strTmpMsg, pStr, 2);
pStr += 2;
std::wstring sexstr = std::wstring(strTmpMsg);
if (sexstr == L"1") //性别
{
m_cardInfo.sex = L"男";
}
else
{
m_cardInfo.sex = L"女";
}
memset(strTmpMsg, 0x00, sizeof(strTmpMsg));
memcpy(strTmpMsg, pStr, 4);
pStr += 4;
std::wstring nationstr = std::wstring(strTmpMsg); //数字
int n = wcstoul(strTmpMsg, NULL, 0);
m_cardInfo.national = GetNationName(n); //民族
memset(strTmpMsg, 0x00, sizeof(strTmpMsg));
memcpy(strTmpMsg, pStr, 16);
pStr += 16;
m_cardInfo.birthData = std::wstring(strTmpMsg); //出生日期
memset(strTmpMsg, 0x00, sizeof(strTmpMsg));
memcpy(strTmpMsg, pStr, 70);
pStr += 70;
m_cardInfo.residenceAddress = std::wstring(strTmpMsg); //地址
memset(strTmpMsg, 0x00, sizeof(strTmpMsg));
memcpy(strTmpMsg, pStr, 36);
pStr += 36;
m_cardInfo.identityCardNo = std::wstring(strTmpMsg); //身份证号
memset(strTmpMsg, 0x00, sizeof(strTmpMsg));
memcpy(strTmpMsg, pStr, 30);
pStr += 30;
m_cardInfo.organIssue = std::wstring(strTmpMsg); //发证机关
memset(strTmpMsg, 0x00, sizeof(strTmpMsg));
memcpy(strTmpMsg, pStr, 16);
pStr += 16;
m_cardInfo.validStartDay = std::wstring(strTmpMsg); //办证日期
memset(strTmpMsg, 0x00, sizeof(strTmpMsg));
memcpy(strTmpMsg, pStr, 16);
pStr += 16;
m_cardInfo.validEndDay = std::wstring(strTmpMsg); //有效期
}
//将数据保存为wlt文件,再调用GetBmp通用接口将wlt文件转码成bmp文件
void ReadCardInfo::WltChangeToBmpFile(unsigned char* pphotoMsg, int len)
{
if (!m_bClosePort)
{
int iret = SDT_ClosePort(m_commPort); //调用GetBmp前必须确认通信端口处于关闭状态
m_bClosePort = true;
WLog(LOG_DEBUG, "SDT_ClosePort ret[%d]\n", iret);
}
const std::string path = "./photo/";
const std::string filename = path + "photo.wlt";
FILE *file = fopen(filename.c_str(), "wb"); //写二进制文件,必须为二进制文件写入,数据才没错,否则会造成格式错误
if (file == NULL)
{
WLog(LOG_ERR, "fopen file[%s] fail\n", filename.c_str());
return;
}
int size = fwrite(pphotoMsg, len, 1, file);
fclose(file);
//wlt到bmp转换,生成的bmp文件为 photo.bmp
int ret = GetBmp((char*)filename.c_str(), 2); //参数1为.wlt文件名字,参数2为接口,1表示串口,2表示usb
if (ret == 1)
{
WLog(LOG_ERR, "GetBmp[%s] success\n", filename.c_str());
}
}
需要包含身份证标准接口的头文件和库文件进来:
sdtapi.h WltRS.h sdtapi.lib WltRS.lib
另wstring转成string的方法:
wstring wstr;
string str;
str = string(wstr.begin(),wstr.end());
直接用string的iterator型构造函数可以转换