记录一下web端调用IC卡读卡器的大致流程

总结一下web端IC卡读卡器的调用方法

公司项目中用到了IC卡,需要实现读写IC卡,并且与服务端交互。IC卡读卡器用的是德卡的D8型号,SDK可以在德卡官网找到,下载链接:德卡SDK下载

官方提供了多种语言的SDK,web端调用首先会想到页面调用OCX的方式。HTML内调用OCX的方法不在赘述,具体可以查看HTML调用OCX。IE浏览器在打开响应页面上需要点“允许阻止的内容”才能成功加载OCX控件,否则无法调用OCX。Chrome及其他浏览器相对复杂,请自行百度。

在操作IC卡之前先了解一下IC卡的一些基础(本文以M1卡为例):
M1卡有16个扇区,即0到15扇区,要读取扇区中的数据,首先要进行密码校验(校验读卡设备中的密码和卡上的密码);要读取哪个扇区的数据就要校验哪个扇区的密码,dc_read或dc_read_hex方法是用的地址是绝对地址(每个扇区4个地址,16个扇区共64个地址,即0到63),校验完0扇区的密码后,能读取0到3地址上的数据,校验完1扇区的密码后,能读取4到7地址上的数据,以此类推。假设扇区号是 sNo,数据块号是bNo,则:sNo号扇区的最小区块号为:4 * sNo,最大区块号为:4 * sNo + 3

对卡的操作基本步骤:
初始化 -> 寻卡 -> 校验密码 -> 操作(读、写、其他操作) -> dc_exit(不执行 exit的话OCX调用会出错)


  • 写卡示例函数
function writeCard(){
	var st; //主要用于返回值
	var lSnr; //本用于取序列号,但在javascript只是当成dc_card函数的一个临时变量

    var messageText = document.getElementById("messageText");
	st = rd.dc_init(100, 115200);
	if(st <= 0) //返回值小于等于0表示失败
	{
		rd.dc_exit();
		messageText.value = messageText.value += "dc_init error!\r\n\r\n";
		return;
	}
	messageText.value = messageText.value += "dc_init ok!\r\n";

	//寻卡,能返回在工作区域内某张卡的序列号
	var snrlen;
	st = rd.dc_card_n(0,snrlen);
	if(st != 0)
	{
		messageText.value = messageText.value + "dc_card_n error!"+ "\r\n";
		rd.dc_exit();
		return;
	}
	messageText.value = messageText.value + "dc_card_n ok!"+ "\r\n";
	//messageText.value = messageText.value + rd.get_bstrRBuffer+ "\r\n";
	messageText.value = messageText.value + rd.get_bstrRBuffer_asc + "\r\n";
	rd.put_bstrSBuffer_asc = "FFFFFFFFFFFF";
	st = rd.dc_authentication_passaddr(0, 11);  //区块地址号根据需求确定
	if (st != 0) {
		messageText.value = messageText.value + "dc_authentication_passaddr error!" + "\r\n\r\n";
		rd.dc_exit();
		return;
	} else {
		messageText.value = messageText.value + "dc_authentication_passaddr ok!" + "\r\n";
	}
	
	messageText.value = messageText.value += "dc_card ok!\r\n";
	messageText.value = messageText.value += "卡序列号:" + rd.get_bstrRBuffer + "\r\n"; //序列号为rd.get_bstrRBuffer,一般有不可显示字符出现
	messageText.value = messageText.value += "卡序列号(ASCII):" + rd.get_bstrRBuffer_asc + "\r\n"; //序列号十六进制ascll码字符串表示为rd.get_bstrRBuffer_asc
	
	//向卡中写入数据,一次必须写一个块
	//第一个参数为块地址
	//在调用dc_write必须前先设置属性rd.put_bstrSBuffer或rd.put_bstrSBuffer_asc
	rd.put_bstrSBuffer_asc = "00000000000000000000000000000007";
	st = rd.dc_write(8);  //区块地址号根据需求确定
	if(st < 0) //返回值小于0表示失败
	{
		messageText.value = messageText.value += "dc_write error!\r\n\r\n";
		rd.dc_exit();
		return;
	}
	messageText.value = messageText.value += "dc_write ok!\r\n";
	
	st = rd.dc_beep(50);
	st = rd.dc_exit();
	if(st < 0){
		messageText += "dc_exit error!\r\n\r\n";
	} else {
		messageText += "dc_exit OK!\r\n\r\n";
	}
}

  • 读卡示例函数:
function readCard(){
	var st; //主要用于返回值
	var lSnr; //本用于取序列号,但在javascript只是当成dc_card函数的一个临时变量

    var messageText = document.getElementById("messageText");
	st = rd.dc_init(100, 115200);
	if(st <= 0) //返回值小于等于0表示失败
	{
		rd.dc_exit();
		messageText.value = messageText.value += "dc_init error!\r\n\r\n";
		return;
	}
	messageText.value = messageText.value += "dc_init ok!\r\n";

	//寻卡,能返回在工作区域内某张卡的序列号
	//第一个参数一般设置为0,表示IDLE模式,一次只对一张卡操作
	//第二个参数在javascript只是当成dc_card函数的一个临时变量,仅在vbscript中调用后能正确返回序列号
	st = rd.dc_card_n(0, lSnr);
	if(st < 0) //返回值小于0表示失败
	{
		messageText.value = messageText.value += "dc_card error!\r\n\r\n";
		rd.dc_exit();
		return;
	}
	
	messageText.value = messageText.value += "dc_card ok!\r\n";
	messageText.value = messageText.value += "卡序列号:" + rd.get_bstrRBuffer + "\r\n"; //序列号为rd.get_bstrRBuffer,一般有不可显示字符出现
	messageText.value = messageText.value += "卡序列号(ASCII):" + rd.get_bstrRBuffer_asc + "\r\n"; //序列号十六进制ascll码字符串表示为rd.get_bstrRBuffer_asc

	//核对密码函数
	//第一个参数为密码验证模式
	//第二个参数为扇区号
	rd.put_bstrSBuffer_asc = "FFFFFFFFFFFF";
	//st = rd.dc_authentication_passaddr(0, 7);
	st = rd.dc_authentication_passaddr(0, 11);	//区块地址号根据需求确定
	if(st < 0) //返回值小于0表示失败
	{
		messageText.value = messageText.value += "dc_authentication error!\r\n\r\n";
		rd.dc_exit();
		return;
	}
	messageText.value = messageText.value += "dc_authentication ok!\r\n";
	
	//st = rd.dc_read(4);
	st = rd.dc_read(8);	//区块地址号根据需求确定
	if(st < 0){
		messageText.value = messageText.value += "dc_read error!\r\n\r\n";
		rd.dc_exit();
		return;
	}
	
	messageText.value = messageText.value += "卡信息: " + rd.get_bstrRBuffer_asc + "\r\n";
	
	st = rd.dc_beep(50);
	st = rd.dc_exit();
	if(st < 0) {
		messageText.value = messageText.value += "dc_exit error!\r\n\r\n";
	} else {
		messageText.value = messageText.value += "dc_exit OK!\r\n\r\n";
	}
	return;
}

初始化过程可以封装成一个函数统一处理。要写入哪些数据、写到哪个扇区、哪个数据块由根据业务需求确定,本文仅仅记录 德卡D8 型号读卡器的调用过程。

PS:代码内用到的JS函数可以查找德卡提供的SDK包内的文档

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页