IC卡特点:
1IC卡的内部存储结构分为16个扇区,从第0区到第15区,每个扇区有独立的密码和权限控制字,可作为卡的密码和权限控制字专用独立的电子钱包,每个扇区有4个块,序号为第0块、第1块、第2块、第3块,每块16个字节,第3块是块,禁止在此存放数据。第0块、第1块、第2块可随意存放数据。但第0区的第0块已被固化了IC卡出厂信息,此块只能读出信息,不可更改。
调用DLL动态库代码:
unsigned char result;
QLibrary mylib("OUR_MIFARE.dll");
if (!mylib.load()) //判断是否正确加载
{
QMessageBox::information(NULL, "提示", "动态库没装载!原因是动态库OUR_MIFARE.dll没放在生成exe文件相同目录下!");
return;
}
pcdbeep mypcdbeep = (pcdbeep)mylib.resolve("pcdbeep");
if (mypcdbeep == NULL) //是否成功连接上 idr_beep()函数
{
mylib.unload();
QMessageBox::information(NULL, "提示", "请检查函数名是否正确!");
return;
}
result = mypcdbeep(30); //这里函数指针调用dll中的idr_beep() 函数
mylib.unload();
if(result > 0)
{
if(result == 23)
{
QMessageBox::information(NULL, "提示", "机器没连上或者驱动没下载");
}
else
{
QMessageBox::information(NULL, "提示", "错误代码:" + QString::number(result));
};
}
读出IC卡数据的代码:
void MainWindow::on_pushButton_3_clicked()//轻松读卡
{
unsigned char ctrlword;//控制字
unsigned char serial[4];//可写数组
unsigned char area;//读出的区号
unsigned char keyA1B0;//AB密码认证
unsigned char picckey[6];//存放卡密码的数组
unsigned char piccdata0_2[48];//下标0~15存放作为读出的块0的数据,下标16~31存放作为读出的块1的数据,下标32~47存放作为读出的块2的数据
unsigned char status;//返回
unsigned char status1;
unsigned char result;
unsigned char piccdata[16]; //卡数据缓冲
//以下控制字含义:读块0、块1、块2,仅读指定序列号的卡,需要每次指定密码
if (ui->radioButton->isChecked())
{
ctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY;
}
else
{//内部密码
ctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;
}
area = ui->comboBox->currentText().toUShort();
keyA1B0 = 1;//用A密码
QString Key_str = ui->lineEdit->text().trimmed();
if(Key_str.length() < 12)
{
QMessageBox::information(NULL, "提示", "密码长度不够12位!");
ui- >lineEdit->setFocus();
return;
}
char c;
for (int var = 0; var < 12; ++var)
{
c = Key_str.at(var).toLatin1();
if(!((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) || (('a' <= c) && (c <= 'f'))))
{
QMessageBox::information(NULL, "提示", "密码输入字符不正确!");
ui- >lineEdit->setSelection(var,1);
ui->lineEdit->setFocus();
return;
}
}
bool ok;
for(int i = 0; i < 6; i++)
{
picckey[i]=QString(Key_str.mid(i*2,2)).toInt(&ok,16);
}
QLibrary mylib("OUR_MIFARE.dll");
if (!mylib.load()) //判断是否正确加载
{
QMessageBox::information(NULL, "提示", "动态库没装载!原因是动态库OUR_MIFARE.dll没放在生成exe文件相同目录下!");
return;
}
piccreadex mypiccreadex = (piccreadex)mylib.resolve("piccreadex");
status = mypiccreadex(ctrlword,serial,area,keyA1B0,picckey,piccdata0_2);
if(status == 0)
{
ui- >lineEdit_2->setText(QString::asprintf("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X ",piccdata0_2[0],piccdata0_2[1],piccdata0_2[2],piccdata0_2[3],piccdata0_2[4],piccdata0_2[5],piccdata0_2[6],piccdata0_2[7],piccdata0_2[8],piccdata0_2[9],piccdata0_2[10],piccdata0_2[11],piccdata0_2[12],piccdata0_2[13],piccdata0_2[14],piccdata0_2[15]));
ui->lineEdit_3->setText(QString::asprintf("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X ",piccdata0_2[16],piccdata0_2[17],piccdata0_2[18],piccdata0_2[19],piccdata0_2[20],piccdata0_2[21],piccdata0_2[22],piccdata0_2[23],piccdata0_2[24],piccdata0_2[25],piccdata0_2[26],piccdata0_2[27],piccdata0_2[28],piccdata0_2[29],piccdata0_2[30],piccdata0_2[31]));
ui->lineEdit_4->setText(QString::asprintf("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X ",piccdata0_2[32],piccdata0_2[33],piccdata0_2[34],piccdata0_2[35],piccdata0_2[36],piccdata0_2[37],piccdata0_2[38],piccdata0_2[39],piccdata0_2[40],piccdata0_2[41],piccdata0_2[42],piccdata0_2[43],piccdata0_2[44],piccdata0_2[45],piccdata0_2[46],piccdata0_2[47]));
piccread mypiccread = (piccread)mylib.resolve("piccread");
status1 = mypiccread(area * 4 + 3,piccdata);
if(status1 == 0)
{
ui->lineEdit_5->setText(QString::asprintf("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X ",piccdata[0],piccdata[1],piccdata[2],piccdata[3],piccdata[4],piccdata[5],piccdata0_2[6],piccdata[7],piccdata[8],piccdata[9],piccdata[10],piccdata[11],piccdata[12],piccdata[13],piccdata[14],piccdata[15]));
}
pcdbeep mypcdbeep = (pcdbeep)mylib.resolve("pcdbeep");
if (mypcdbeep == NULL) //是否成功连接上 idr_beep()函数
{
mylib.unload();
QMessageBox::information(NULL, "提示", "请检查函数名是否正确!");
return;
}
result = mypcdbeep(30); //这里函数指针调用dll中的idr_beep() 函数
mylib.unload();
}
else if(status == 8)
{
ui->lineEdit_2->clear();
ui->lineEdit_3->clear();
ui->lineEdit_4->clear();
QMessageBox::information(NULL, "提示", "寻卡错误,根本就没有卡在感应区");
}
else if(status == 12)
{
ui->lineEdit_2->clear();
ui->lineEdit_3->clear();
ui->lineEdit_4->clear();
QMessageBox::information(NULL, "提示", "密码认证失败");
}
}
写入数据到IC卡的代码:
void MainWindow::on_pushButton_12_clicked()//轻松写卡
{
unsigned char serial[4];//可写数组
unsigned char area;//读出的区号
unsigned char keyA1B0;//AB密码认证
unsigned char picckey[6];//存放卡密码的数组
unsigned char piccdata0_2[48];//下标0~15存放作为读出的块0的数据,下标16~31存放作为读出的块1的数据,下标32~47存放作为读出的块2的数据
unsigned char status;//返回
unsigned char result;
char s;
//以下控制字含义:读块0、块1、块2,仅读指定序列号的卡,需要每次指定密码
if (ui->radioButton->isChecked())
{
ctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY + NEEDHALT;
}
else
{//内部密码
ctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;
}
area = ui->comboBox->currentText().toUShort();
keyA1B0 = 1;//用A密码
QString Key_str = ui->lineEdit->text().trimmed();
if(Key_str.length() < 12)
{
QMessageBox::information(NULL, "提示", "密码长度不够12位!");
ui- >lineEdit->setFocus();
return;
}
char c;
for (int var = 0; var < 12; ++var)
{
c = Key_str.simplified().at(var).toLatin1();
if(!((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) || (('a' <= c) && (c <= 'f'))))
{
QMessageBox::information(NULL, "提示", "密码输入字符不正确!");
//ui- >lineEdit->setSelection(var,1);
ui->lineEdit->setSelection(var,1);
ui->lineEdit->setFocus();
return;
}
}
bool ok;
for(int i = 0; i < 6; i++)
{
picckey[i]=QString(Key_str.mid(i*2,2)).toInt(&ok,16);
}
//第0块数据
QChar ch;
QString writinf = ui- >lineEdit_2->text().trimmed();
QString writinf1 = "";
int m = 0;
int n = 0;
ch = writinf.at(0);
s = writinf.at(0).toLatin1();
for(int i=0; i< writinf.length() ; i++)
{
ch = writinf.at(i);
s = writinf.at(i).toLatin1();
if((('0' <= s) && (s <= '9')) || (('A' <= s) && (s <= 'F')) || (('a' <= s) && (s <= 'f')))
{
writinf1 += ch;
n++;
if(n==2)
{
piccdata0_2[m++] = writinf1.toInt(&ok,16);
writinf1 = "";
n = 0;
if(m >=16)
{
break;
}
}
}
else if(s == ' ')
{
}
else
{
QMessageBox::information(NULL, "提示", "写卡数据错误,请输入正确的16进制数据!");
ui->lineEdit_2->setSelection(i,1);
ui->lineEdit_2->setFocus();
return;
}
}
if(m< 16)
{
QMessageBox::information(NULL, "提示", "第0块输入数据不足!");
ui- >lineEdit_2->setFocus();
return;
}
//第1块数据
writinf = ui->lineEdit_3->text().trimmed();
QString writinf2 = "";
m = 16;
for(int i=0; i< writinf.length() ; i++)
{
ch = writinf.at(i);
s = writinf.at(i).toLatin1();
if((('0' <= s) && (s <= '9')) || (('A' <= s) && (s <= 'F')) || (('a' <= s) && (s <= 'f')))
{
writinf2 += ch;//12 34
n++;//2
if(n==2)
{
piccdata0_2[m++] = writinf2.toInt(&ok,16);
writinf2 = "";
n = 0;
if(m >=32)
{
break;
}
}
}
else if(s == ' ')
{
}
else
{
QMessageBox::information(NULL, "提示", "写卡数据错误,请输入正确的16进制数据!");
qDebug() < < i;
ui- >lineEdit_3->setSelection(i,1);
ui->lineEdit_3->setFocus();
return;
}
}
if(m< 16)
{
QMessageBox::information(NULL, "提示", "第1块输入数据不足!");
ui- >lineEdit_3->setFocus();
return;
}
//第2块数据
writinf = ui->lineEdit_4->text().trimmed();
QString writinf3 = "";
m = 32;
for(int i=0; i< writinf.length() ; i++)
{
ch = writinf.at(i);
s = writinf.at(i).toLatin1();
if((('0' <= s) && (s <= '9')) || (('A' <= s) && (s <= 'F')) || (('a' <= s) && (s <= 'f')))
{
writinf3 += ch;//12 34
n++;//2
if(n==2)
{
piccdata0_2[m++] = writinf3.toInt(&ok,16);
writinf3 = "";
n = 0;
if(m >=48)
{
break;
}
}
}
else if(s == ' ')
{
}
else
{
QMessageBox::information(NULL, "提示", "写卡数据错误,请输入正确的16进制数据!");
ui->lineEdit_4->setSelection(i,1);
ui->lineEdit_4->setFocus();
return;
}
}
if(m< 48)
{
QMessageBox::information(NULL, "提示", "第2块输入数据不足!");
ui- >lineEdit_4->setFocus();
return;
}
QLibrary mylib("OUR_MIFARE.dll");
if (!mylib.load()) //判断是否正确加载
{
QMessageBox::information(NULL, "提示", "动态库没装载!原因是动态库OUR_MIFARE.dll没放在生成exe文件相同目录下!");
return;
}
piccwriteex mypiccwriteex = (piccwriteex)mylib.resolve("piccwriteex");
status = mypiccwriteex(ctrlword,serial,area,keyA1B0,picckey,piccdata0_2);
if(status == 0)
{
pcdbeep mypcdbeep = (pcdbeep)mylib.resolve("pcdbeep");
if (mypcdbeep == NULL) //是否成功连接上 idr_beep()函数
{
mylib.unload();
QMessageBox::information(NULL, "提示", "请检查函数名是否正确!");
return;
}
result = mypcdbeep(30); //这里函数指针调用dll中的idr_beep() 函数
mylib.unload();
QMessageBox::information(NULL, "提示", "写卡成功!");
}
else if(status == 8)
{
ui->lineEdit_2->clear();
ui->lineEdit_3->clear();
ui->lineEdit_4->clear();
QMessageBox::information(NULL, "提示", "寻卡错误,根本就没有卡在感应区");
}
else if(status == 12)
{
ui->lineEdit_2->clear();
ui->lineEdit_3->clear();
ui->lineEdit_4->clear();
QMessageBox::information(NULL, "提示", "密码认证失败");
}
}
修改A,B区密码:
void MainWindow::on_pushButton_14_clicked()
{
unsigned char ctrlword;//控制字
unsigned char serial[4];//可写数组
unsigned char area;//读出的区号
unsigned char keyA1B0;//AB密码认证
unsigned char piccoldkey[6];//存放卡原始密码的数组
unsigned char piccdata[17];//存放卡新A密码(也就是准备改成的密码)、密码权限访问字、新B密码的数组、指定更改项目的标志
unsigned char status;//返回
unsigned char result;
if (ui->radioButton->isChecked())
{
ctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN + EXTERNKEY + NEEDHALT;
}
else
{//内部密码
ctrlword = BLOCK0_EN + BLOCK1_EN + BLOCK2_EN;
}
area = ui->comboBox->currentText().toUShort();
keyA1B0 = 1;//用A密码
QString Key_str = ui->lineEdit->text().trimmed();
if(Key_str.length() < 12)
{
QMessageBox::information(NULL, "提示", "密码长度不够12位!");
ui- >lineEdit->setFocus();
return;
}
char c;
for (int var = 0; var < 12; ++var)
{
c = Key_str.simplified().at(var).toLatin1();
if(!((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) || (('a' <= c) && (c <= 'f'))))
{
QMessageBox::information(NULL, "提示", "密码输入字符不正确!");
ui- >lineEdit->setSelection(var,1);
ui->lineEdit->setFocus();
return;
}
}
bool ok;
for(int i = 0; i < 6; i++)
{
piccoldkey[i]=QString(Key_str.mid(i*2,2)).toInt(&ok,16);
}
QChar ch;
QString writinf = ui- >lineEdit_5->text().trimmed();
QString writinf4 = "";
int m = 0;
int n = 0;
char s;
for(int i=0; i< writinf.length() ; i++)
{
ch = writinf.at(i);
s = writinf.at(i).toLatin1();
if((('0' <= s) && (s <= '9')) || (('A' <= s) && (s <= 'F')) || (('a' <= s) && (s <= 'f')))
{
writinf4 += ch;
n++;
if(n==2)
{
piccdata[m++] = writinf4.toInt(&ok,16);
writinf4 = "";
n = 0;
if(m >=16)
{
break;
}
}
}
else if(s == ' ')
{
}
else
{
QMessageBox::information(NULL, "提示", "写卡数据错误,请输入正确的16进制数据!");
ui->lineEdit_5->setSelection(i,1);
ui->lineEdit_5->setFocus();
return;
}
}
if(m< 16)
{
QMessageBox::information(NULL, "提示", "第3块输入数据不足!");
ui- >lineEdit_5->setFocus();
return;
}
QLibrary mylib("OUR_MIFARE.dll");
if (!mylib.load()) //判断是否正确加载
{
QMessageBox::information(NULL, "提示", "动态库没装载!原因是动态库OUR_MIFARE.dll没放在生成exe文件相同目录下!");
return;
}
piccchangesinglekeyex mypiccchangesinglekeyex = (piccchangesinglekeyex)mylib.resolve("piccchangesinglekeyex");
status = mypiccchangesinglekeyex(ctrlword,serial,area,keyA1B0,piccoldkey,piccdata);
QMessageBox::warning(this, "警告", "你确定修改密码控制块的数据吗 ?此数据块如果改写错误,数据卡将会被限制", QMessageBox::Ok, QMessageBox::Cancel);
if(status == 0)
{
QMessageBox::information(NULL, "提示", "操作成功,写卡数据有效!");
pcdbeep mypcdbeep = (pcdbeep)mylib.resolve("pcdbeep");
if (mypcdbeep == NULL) //是否成功连接上 idr_beep()函数
{
mylib.unload();
QMessageBox::information(NULL, "提示", "请检查函数名是否正确!");
return;
}
result = mypcdbeep(30); //这里函数指针调用dll中的idr_beep() 函数
mylib.unload();
}
else if(status == 8)
{
QMessageBox::information(NULL, "提示", "寻卡错误,根本就没有卡在感应区");
}
else if(status == 12)
{
QMessageBox::information(NULL, "提示", "密码认证失败");
}
}
审核编辑 黄宇
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
IC卡
+关注
关注
2文章
175浏览量
37138 -
Qt
+关注
关注
2文章
322浏览量
41153
发布评论请先 登录
相关推荐
热点推荐
逆风C++QT中控台逆向课程
,成为众多应用程序开发的热门选择。尤其在工业中控系统中,QT的多线程处理能力和消息通信机制,为复杂业务逻辑的高效执行提供了坚实基础。然而,当需要对这些QT应用进行逆向分析时,多线程逻辑
RK3562 单板机图形用户界面开发完全手册:Qt Creator 配置与 LVGL 案例详解(二)
程序自启动与 GPU 加速实现。通过图片显示、LED 控制等案例,明确关键代码与测试步骤。创龙科技以清晰实操指引,帮助开发者高效完成 Qt 图形界面开发,适用于工业控制、智能终端等场景
RK3562 单板机图形用户界面开发完全手册:Qt Creator 配置与 LVGL 案例详解(一)
程序自启动与 GPU 加速实现。通过图片显示、LED 控制等案例,明确关键代码与测试步骤。创龙科技以清晰实操指引,帮助开发者高效完成 Qt 图形界面开发,适用于工业控制、智能终端等场景
matlab调用dll动态库函数,死机问题,如何强行跳出?
matlab调用dll动态库中的函数,例如图莫斯,发送数据时,经常会卡死,是否有办法限制时间,比如3秒,没有回应,就强行结束函数调用。执行后续逻辑。
发表于 12-31 10:14
SD卡读写均衡失效问题分析
一、读写均衡失效引发的核心问题 读写均衡(磨损均衡,Wear Leveling)是SD卡固件通过算法将数据均匀分配到闪存芯片各单元,避免局部单元过度擦写的关键机制。瀚海微SD卡出现
鹰速光电的Cameralink采集卡接入Labview办法
使用鹰速光电的Cameralink转USB采集卡,型号:ES-CV-CLF-U3或者ES-CV-CLB-U3,除了提供开放的SDK支持常用的VC、C#、QT等开发。还提供的便利的Labview
发表于 12-25 21:48
RK3506开发板QT Creator开发手册,交叉编译工具链与QT应用示例,入门必备
本文基于触觉智能RK3506核心板/开发板介绍QTCreator交叉编译配置与QT应用示例。如需购买开发板进行评估验证简介QTCreatorQtCreator是由TheQtCompany开发
创龙 瑞芯微 RK3588 国产2.4GHz八核 工业开发板—Qt工程编译、GPU核心使用说明
及 Kits 配置;还介绍评估板运行 Qt 程序、程序自启动设置,以及通过 textures 案例演示 Qt+OpenGL 调用 GPU
【汇思博SEEK100开发板试用体验】在开发板鸿蒙OS搭建QT开发环境
应用所需的功能逻辑。比如与开发板的硬件功能进行交互,若要调用开发板的摄像头功能,可通过相关的 Qt 多媒体库结合鸿蒙系统提供的摄像头接口进行
发表于 08-24 18:34
【飞凌T527N开发板试用】QT应用开发
qt介绍
Qt 是一个跨平台的C++ 应用程序开发框架 ,由挪威公司 Trolltech(现为 The Qt Company)
发表于 08-19 15:04
【EASY EAI Orin Nano开发板试用体验】03-安装QT Creator和QT6
。
内核编译
内核编译这块其实可以参考官方的内核开发流程说明,但是官方有所更新,所以有些地方需要动态修改一下。
首先,安装编译需要的软件。
sudo apt update
sudo apt upgrade
发表于 07-07 14:37
QT调用动态库开发IC卡读写程序
评论