身份证读卡器标准接口使用

原创 2017年09月21日 14:13:50
#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型构造函数可以转换

二代身份证读卡器脚本

  • 2009年05月08日 20:55
  • 4KB
  • 下载

二代身份证读卡器API接口

  • 2010年12月15日 17:36
  • 9.45MB
  • 下载

原装HID读卡器,我们的价格只是别人的七折、八折或九折!

 原装HID,我们的价格只是别人的七折、八折或九折!提供HID读卡器,HID卡,HID门禁系统。广州凌顿电脑科技有限公司1998年来一直专注于安防行业。现为美国galaxy门禁系统亚洲总代理。我们的宗...
  • fuqiusheng
  • fuqiusheng
  • 2008年05月16日 15:19
  • 277

二代身份证读卡器接口函数Delphi声明

查看串口当前波特率 function SDT_GetCOMBaud(iPort: integer; puiBaudRate: Pinteger): integer;stdcall;External'...
  • zisongjia
  • zisongjia
  • 2017年03月03日 09:56
  • 1136

二代身份证读卡器接口

  • 2013年02月25日 09:45
  • 1KB
  • 下载

最近的项目中用到读卡器,用的华视身份证阅读器,附上SDK使用手册

// 最近的项目中用到读卡器,用的华视身份证阅读器,附上SDK使用手册 1.定义 应用函数开发包含下列文件: termb.dll      API函数的动...
  • dyllove98
  • dyllove98
  • 2013年06月17日 22:07
  • 2223

二代身份证读卡器的二次开发

1. 基本信息处理 因为二代身份证里编码为GB13000,汉字在java处理中存在问题,处理思想为先把16进制字节高低位互换(汉字字节即可),然后用UTF-16转换成中文字符 2. 图片信息处...
  • msliang
  • msliang
  • 2012年11月05日 18:05
  • 1984

神思二代身份证读卡器Demo的C++版本

在某宝上买了一个神思二代身份证读卡器,给的DEMO实在是....无语了,无奈,自己研究写了一个。 1、首先,需要把licence.dat和Termb.lic文件放到C盘根目录下。      请注意...
  • dafenqie
  • dafenqie
  • 2016年12月06日 17:41
  • 1074

C#调用C++DLL 使用 德卡 读卡器 获取身份证信息

公司一个项目用到了德卡读卡器的设备,想在原有厂商给的C++ DLL的基础上再做一层封装,方便以后项目的使用,拿来DLL和接口文档就开干了。 在这里记录下,也分享给之后或许有需要的朋友。...
  • buffoon1900
  • buffoon1900
  • 2016年01月06日 11:20
  • 2200

神思二代身份证读卡器Demo——C#

//之前就用过神思二代身份证读卡器,后来有很多网友都问我怎么用,    //今天抽空做个Demo给大家参考一下,在做这个Demo之前,    //读卡器已不在我身边,所以无法测试。之前做实验的时候, ...
  • linweibo397876058
  • linweibo397876058
  • 2011年07月21日 13:27
  • 5198
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:身份证读卡器标准接口使用
举报原因:
原因补充:

(最多只允许输入30个字)