当前位置: 首页 > news >正文

Qt_C++读写NFC标签Ntag支持windows国产linux操作系统

本示例使用的发卡器:Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/智能海报/-淘宝网 (taobao.com) 

ntag2标签存储结构说明
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QDebug>
#include "QLibrary"
#include "QMessageBox"//本示例可在windows、linux系统内编译、运行
//判断windows、linux系统,声明动态库函数----------------------------------------------------------------------------------------------------------------------------------------------
//让读写器发出声音
typedef  unsigned char (*pcdbeep)(unsigned long xms);
#ifdef Q_OS_WINpcdbeep mypcdbeep = (pcdbeep)QLibrary("OUR_MIFARE.dll").resolve("pcdbeep");
#elsepcdbeep mypcdbeep = (pcdbeep)QLibrary("./libOURIDR.so").resolve("pcdbeep");
#endif//返回本读写器独一无二的设备编号
typedef  unsigned char (*pcdgetdevicenumber)(unsigned char *devicenumber);
#ifdef Q_OS_WINpcdgetdevicenumber mypcdgetdevicenumber = (pcdgetdevicenumber)QLibrary("OUR_MIFARE.dll").resolve("pcdgetdevicenumber");
#elsepcdgetdevicenumber mypcdgetdevicenumber = (pcdgetdevicenumber)QLibrary("./libOURIDR.so").resolve("pcdgetdevicenumber");
#endif//读取卡片的uid
typedef  unsigned char (*piccrequest_ul)(unsigned char *serial);
#ifdef Q_OS_WINpiccrequest_ul mypiccrequest_ul = (piccrequest_ul)QLibrary("OUR_MIFARE.dll").resolve("piccrequest_ul");
#elsepiccrequest_ul mypiccrequest_ul = (piccrequest_ul)QLibrary("./libOURIDR.so").resolve("piccrequest_ul");
#endif//读取卡片4页数据
typedef  unsigned char (*piccread_ul)(unsigned char blockadd,unsigned char *piccdata);
#ifdef Q_OS_WINpiccread_ul mypiccread_ul = (piccread_ul)QLibrary("OUR_MIFARE.dll").resolve("piccread_ul");
#elsepiccread_ul mypiccread_ul = (piccread_ul)QLibrary("./libOURIDR.so").resolve("piccread_ul");
#endif//写1页数据
typedef  unsigned char (*piccwrite_ul)(unsigned char blockadd,unsigned char *piccdata);
#ifdef Q_OS_WINpiccwrite_ul mypiccwrite_ul = (piccwrite_ul)QLibrary("OUR_MIFARE.dll").resolve("piccwrite_ul");
#elsepiccwrite_ul mypiccwrite_ul = (piccwrite_ul)QLibrary("./libOURIDR.so").resolve("piccwrite_ul");
#endif//认证卡片密码
typedef  unsigned char (*piccauthkey_ntag)(unsigned char *picckey,unsigned char *piccntagpack);
#ifdef Q_OS_WINpiccauthkey_ntag mypiccauthkey_ntag = (piccauthkey_ntag)QLibrary("OUR_MIFARE.dll").resolve("piccauthkey_ntag");
#elsepiccauthkey_ntag mypiccauthkey_ntag = (piccauthkey_ntag)QLibrary("./libOURIDR.so").resolve("piccauthkey_ntag");
#endif//读取卡的版本号及型号
typedef  unsigned char (*piccgetversion_ntag)(unsigned char *mypiccversiondata);
#ifdef Q_OS_WINpiccgetversion_ntag mypiccgetversion_ntag = (piccgetversion_ntag)QLibrary("OUR_MIFARE.dll").resolve("piccgetversion_ntag");
#elsepiccgetversion_ntag mypiccgetversion_ntag = (piccgetversion_ntag)QLibrary("./libOURIDR.so").resolve("piccgetversion_ntag");
#endif//读取卡的签字信息
typedef  unsigned char (*piccreadsig_ntag)(unsigned char *piccsigdata);
#ifdef Q_OS_WINpiccreadsig_ntag mypiccreadsig_ntag = (piccreadsig_ntag)QLibrary("OUR_MIFARE.dll").resolve("piccreadsig_ntag");
#elsepiccreadsig_ntag mypiccreadsig_ntag = (piccreadsig_ntag)QLibrary("./libOURIDR.so").resolve("piccreadsig_ntag");
#endif//读取卡操作的单向计数器(卡操作流水号)
typedef  unsigned char (*piccreadcnt_ntag)(unsigned char *mypicccntdata);
#ifdef Q_OS_WINpiccreadcnt_ntag mypiccreadcnt_ntag = (piccreadcnt_ntag)QLibrary("OUR_MIFARE.dll").resolve("piccreadcnt_ntag");
#elsepiccreadcnt_ntag mypiccreadcnt_ntag = (piccreadcnt_ntag)QLibrary("./libOURIDR.so").resolve("piccreadcnt_ntag");
#endif//锁定页数据
typedef  unsigned char (*picclock_ntag)(unsigned char locktype,unsigned char *mypicclockdata);
#ifdef Q_OS_WINpicclock_ntag mypicclock_ntag = (picclock_ntag)QLibrary("OUR_MIFARE.dll").resolve("picclock_ntag");
#elsepicclock_ntag mypicclock_ntag = (picclock_ntag)QLibrary("./libOURIDR.so").resolve("picclock_ntag");
#endif//初始化卡,开启读写卡密码保护功能
typedef  unsigned char (*piccinit_ntag)(unsigned char ctrlword,unsigned char *serial,unsigned char *pickey,unsigned char *configdata);
#ifdef Q_OS_WINpiccinit_ntag mypiccinit_ntag = (piccinit_ntag)QLibrary("OUR_MIFARE.dll").resolve("piccinit_ntag");
#elsepiccinit_ntag mypiccinit_ntag = (piccinit_ntag)QLibrary("./libOURIDR.so").resolve("piccinit_ntag");
#endif//轻松读卡
typedef  unsigned char (*piccreadex_ntag)(unsigned char ctrlword,unsigned char *serial,unsigned char *pickey,unsigned char blockadd,unsigned char blocksize,unsigned char *picdata);
#ifdef Q_OS_WINpiccreadex_ntag mypiccreadex_ntag = (piccreadex_ntag)QLibrary("OUR_MIFARE.dll").resolve("piccreadex_ntag");
#elsepiccreadex_ntag mypiccreadex_ntag = (piccreadex_ntag)QLibrary("./libOURIDR.so").resolve("piccreadex_ntag");
#endif//轻松写卡
typedef  unsigned char (*piccwriteex_ntag)(unsigned char ctrlword,unsigned char *serial,unsigned char *pickey,unsigned char blockadd,unsigned char blocksize,unsigned char *picdata);
#ifdef Q_OS_WINpiccwriteex_ntag mypiccwriteex_ntag = (piccwriteex_ntag)QLibrary("OUR_MIFARE.dll").resolve("piccwriteex_ntag");
#elsepiccwriteex_ntag mypiccwriteex_ntag = (piccwriteex_ntag)QLibrary("./libOURIDR.so").resolve("piccwriteex_ntag");
#endif//检测输入数据是否为16进制数------------------------------------------------------------------------------------------------------------------------------------------------------------
static bool checkinput(QString inputstr){QString inputyes="0123456789abcdefABCDEF";for(int i=0;i<inputstr.length();i++){if(inputyes.contains(inputstr.mid(i,1),Qt::CaseSensitive)){}else{return false;}}return true;
}//检测动态库文件是否在运行目录内----------------------------------------------------------------------------------------------------------------------------------------------------------
static bool checkdllos(){
#ifdef Q_OS_WINQLibrary mylib("OUR_MIFARE.dll");if (!mylib.load()){                //判断windows系统下,OUR_MIFARE.dll是否在运行目录内QMessageBox::information(NULL, "提示", "请将OUR_MIFARE.dll文件拷贝到生成exe文件相同目录下!");return false;}else{return true;}
#elseQLibrary mylib("./libOURIDR.so");if (!mylib.load()){                //判断linux系统下,libOURIDR.so是否正运行目录内QMessageBox::information(NULL, "提示", "请将libOURIDR.so文件拷贝到生成的运行文件相同目录下!");return false;}else{return true;}
#endif
}//显示返回的错误代码信息-----------------------------------------------------------------------------------------------------------------------------------------------------------------
static void disperrinf(unsigned char result){switch (result) {case 1:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",0~2块都没读出来,可能刷卡太块。但卡序列号已被读出来!");break;case 2:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",第0块已被读出,但1~2块读取失败。卡序列号已被读出来!");break;case 3:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",第0、1块已被读出,但2块读取失败。卡序列号已被读出来!");break;case 8:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",未寻到卡,请重新拿开卡后再放到感应区!");break;case 9:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",有多张卡在感应区,寻卡过程中防冲突失败,读序列吗错误!");break;case 10:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",该卡可能已被休眠,无法选中卡片!");break;case 11:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",密码装载失败!");break;case 12:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",卡片密码认证失败!");break;case 13:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",读页数据失败,可能需要验证密码!");break;case 14:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",写页数据失败,可能需要验证密码!");break;case 18:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",写UID失败,此卡可能不是UID卡!");break;case 22:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",动态库或驱动程序异常!");break;case 23:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",驱动程序错误或发卡器尚未安装!");break;case 24:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",操作超时,一般是动态库没有反应!");break;case 25:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",发送字数不够!");break;case 26:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",驱动程序错误或发卡器尚未安装!");break;case 27:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",操作超时,一般是动态库没有反应!");break;case 28:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",发送字数不够!");break;default:QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",未知的错误信息!");break;}
}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pb_beep_clicked()
{if(!checkdllos()){return;}      //判断运行目录内动态库文件是否存在unsigned char status;status = mypcdbeep(30);if(status==0){}else{disperrinf(status);}
}void MainWindow::on_pb_getdevnum_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char devicenumber[4];    //设备编号缓冲unsigned char status;             //函数返回状态status = mypcdgetdevicenumber(devicenumber);if(status==0){mypcdbeep(30);QMessageBox::information(NULL, "提示", QString::asprintf("设备编号:%03d-%03d-%03d-%03d", devicenumber[0],devicenumber[1],devicenumber[2],devicenumber[3]));}else{disperrinf(status);}
}void MainWindow::on_pb_request_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态ui->lineEdit_uid->setText("");status = mypiccrequest_ul(mypiccserial);if(status==0){mypcdbeep(30);QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);}else{disperrinf(status);}
}void MainWindow::on_pb_read4page_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char blockadd;           //读卡起始页地址unsigned char mypicdata[16];      //读卡数据缓冲ui->lineEdit_uid->setText("");ui->plainTextEdit_data->setPlainText("");status = mypiccrequest_ul(mypiccserial);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);blockadd=ui->spinBox_star_rw->value();status = mypiccread_ul(blockadd,mypicdata);if(status==0){QString datastr="" ;for (int i = 0; i < 16; i++) {datastr=datastr+QString::asprintf("%02X ",mypicdata[i]);}ui->plainTextEdit_data->setPlainText(datastr);mypcdbeep(30);QMessageBox::information(NULL, "提示","读卡成功,卡号:"+uidstr );}else{disperrinf(status);}}else{disperrinf(status);}
}void MainWindow::on_pb_write1page_clicked()
{if(!checkdllos()){return;}      //判断运行目录内动态库文件是否存在//检测写卡数据unsigned char piccdatabuf[255]; //写卡数据缓冲QChar ch;QString writinf = ui->plainTextEdit_data->toPlainText().trimmed();QString writinf1 = "";int m = 0;int n = 0;char s;if(writinf.length()<1){QMessageBox::critical(NULL, "提示", "请输入正确的16进制写卡数据!");ui->plainTextEdit_data->setFocus();return;}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){bool ok;piccdatabuf[m++] = writinf1.toInt(&ok,16);writinf1 = "";n = 0;if(m>=49){break;}}}else if(s == ' '){}else{QMessageBox::critical(NULL, "提示", "写卡数据错误,请输入正确的16进制数据!");ui->plainTextEdit_data->setFocus();return;}}unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char blockadd;           //写卡起始页地址ui->lineEdit_uid->setText("");status = mypiccrequest_ul(mypiccserial);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);blockadd=ui->spinBox_star_rw->value();status = mypiccwrite_ul(blockadd,piccdatabuf);if(status==0){            mypcdbeep(30);QMessageBox::information(NULL, "提示","写卡成功,卡号:"+uidstr );}else{disperrinf(status);}}else{disperrinf(status);}
}void MainWindow::on_pb_auth_clicked()
{if(!checkdllos()){return;}      //判断运行目录内动态库文件是否存在unsigned char mypickey[4];      //认证密码QString keystr=ui->lineEdit_authkey->text().trimmed();if(keystr.length()==8 and checkinput(keystr)){bool ok;for(int i=0;i<4;i++){mypickey[i]=QString(keystr.mid(i*2,2)).toInt(&ok,16);}}else{QMessageBox::critical(NULL, "提示","请输入8位16进制卡认证密码!");ui->lineEdit_authkey->setFocus();return;}unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char mypiccntagpack[2];  //认证后返回的确认码ui->lineEdit_uid->setText("");status = mypiccrequest_ul(mypiccserial);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);status = mypiccauthkey_ntag(mypickey,mypiccntagpack);if(status==0){mypcdbeep(30);QMessageBox::information(NULL, "提示","卡密码认证成功,卡号:"+uidstr );}else{disperrinf(status);}}else{disperrinf(status);}
}void MainWindow::on_pb_getver_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char mypiccversiondata[8];      //卡版本及型号缓冲ui->lineEdit_uid->setText("");status = mypiccrequest_ul(mypiccserial);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);status = mypiccgetversion_ntag(mypiccversiondata);if(status==0){QString datastr="" ;for (int i = 0; i < 8; i++) {datastr=datastr+QString::asprintf("%02X",mypiccversiondata[i]);}mypcdbeep(30);QMessageBox::information(NULL, "提示","读卡成功,卡号:"+uidstr +",版本型号:"+datastr);}else{disperrinf(status);}}else{disperrinf(status);}
}void MainWindow::on_pb_getsign_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char piccsigdata[32];    //卡签名信息ui->lineEdit_uid->setText("");status = mypiccrequest_ul(mypiccserial);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);status = mypiccreadsig_ntag(piccsigdata);if(status==0){QString datastr="" ;for (int i = 0; i < 32; i++) {datastr=datastr+QString::asprintf("%02X",piccsigdata[i]);}mypcdbeep(30);QMessageBox::information(NULL, "提示","卡签字信息:"+datastr );}else{disperrinf(status);}}else{disperrinf(status);}
}void MainWindow::on_pb_getcounter_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char mypicccntdata[3];   //卡操作计数器缓冲ui->lineEdit_uid->setText("");status = mypiccrequest_ul(mypiccserial);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);status = mypiccreadcnt_ntag(mypicccntdata);if(status==0){QString datastr="" ;for (int i = 0; i < 3; i++) {datastr=datastr+QString::asprintf("%02X",mypicccntdata[i]);}mypcdbeep(30);QMessageBox::information(NULL, "提示","读卡成功,卡号:"+uidstr +",卡操作的单向计数器:"+datastr);}else{if(status==13){QMessageBox::critical(NULL, "提示","卡号:"+uidstr +",可能是计数器功能尚未启用或卡片不支持计数功能!");}else{disperrinf(status);}}}else{disperrinf(status);}
}void MainWindow::on_pb_staticlock_clicked()
{if(!checkdllos()){return;}            //判断运行目录内动态库文件是否存在int answ=QMessageBox::question (this, "警告", "你确定要开启卡片的静态锁吗 ?锁定后3-15页数据不能再次修改!", QMessageBox::Ok, QMessageBox::Cancel);if (answ ==1024){unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char mypicclockdata[4];  //锁定状态ui->lineEdit_uid->setText("");status = mypiccrequest_ul(mypiccserial);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);mypicclockdata[0] = 0x00;mypicclockdata[1] = 0x00;mypicclockdata[2] = 0xF9;mypicclockdata[3] = 0x00;status = mypicclock_ntag(0,mypicclockdata);if(status==0){mypcdbeep(30);QMessageBox::information(NULL, "提示","3~15页静态锁数据写入成功!" );}else{disperrinf(status);}}else{disperrinf(status);}}
}void MainWindow::on_pb_dynamiclock_clicked()
{if(!checkdllos()){return;}            //判断运行目录内动态库文件是否存在int answ=QMessageBox::question (this, "警告", "你确定要开启卡片的动态锁吗 ?锁定后16及以后的页数据不能再次修改!", QMessageBox::Ok, QMessageBox::Cancel);if (answ ==1024){unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char mypicclockdata[4];  //锁定状态ui->lineEdit_uid->setText("");status = mypiccrequest_ul(mypiccserial);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);mypicclockdata[0] = 0x01;mypicclockdata[1] = 0x01;mypicclockdata[2] = 0x00;mypicclockdata[3] = 0x00;status = mypicclock_ntag(1,mypicclockdata);if(status==0){mypcdbeep(30);QMessageBox::information(NULL, "提示","16之后页动态锁数据写入成功!" );}else{disperrinf(status);}}else{disperrinf(status);}}
}void MainWindow::on_pb_init_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char myctrlword;         //写卡控制字unsigned char mypiccdata[16];     //卡配置数据unsigned char mypickey[4];        //卡片认证密码ui->lineEdit_uid->setText("");if(ui->checkbox_sele->isChecked()){     //选择先认证卡密码成功再读写卡QString authkey=ui->lineEdit_authkey->text().trimmed();if(authkey.length()==8 and checkinput(authkey)){for(int i=0;i<4;i++){bool ok;mypickey[i]=QString(authkey.mid(i*2,2)).toInt(&ok,16);}myctrlword=0x10;}else{QMessageBox::critical(NULL, "提示","请输入8位16进制认证密码!");ui->lineEdit_authkey->setFocus();return;}}else{myctrlword=0x00;    //无需认证卡密码}if(ui->comboBox_init->currentIndex()==0){   //开启卡密码保护功能int answ=QMessageBox::question (this, "警告", "    您确定要开启卡片的密码保护功能吗 ?开启密码保护功能后需记住卡片的新密码,否则卡片将报废!", QMessageBox::Ok, QMessageBox::Cancel);if (answ !=1024){return;}mypiccdata[0] = 0x00;mypiccdata[1] = 0x00;mypiccdata[2] = 0x00;mypiccdata[3] = ui->spinBox_star->value();      //密码保护起始页地址myctrlword=myctrlword+0x01;mypiccdata[4] = (ui->spinBox_num->value() % 8); //认证次数if(ui->checkBox_readen->isChecked()){mypiccdata[4] =mypiccdata[4] +0x80;         //开启读密码保护}mypiccdata[5] = 0x00;    //启用计数器mypiccdata[6] = 0x00;mypiccdata[7] = 0x00;myctrlword=myctrlword+0x02;QString newkey=ui->lineEdit_authkey->text().trimmed();if(newkey.length()==8 and checkinput(newkey)){for(int i=0;i<4;i++){bool ok;mypiccdata[8+i]=QString(newkey.mid(i*2,2)).toInt(&ok,16);}mypiccdata[12] = 0x16;mypiccdata[13] = 0x16;mypiccdata[14] = 0x00;mypiccdata[15] = 0x00;myctrlword=myctrlword+0x04;}else{QMessageBox::critical(NULL, "提示","请输入8位16进制认证密码!");return;}}else{      //取消卡密码保护功能mypiccdata[0] = 0x00;mypiccdata[1] = 0x00;mypiccdata[2] = 0x00;mypiccdata[3] = 0xff;myctrlword=myctrlword+0x01;mypiccdata[4] = 0x00;mypiccdata[5] = 0x00;mypiccdata[6] = 0x00;mypiccdata[7] = 0x00;myctrlword=myctrlword+0x02;}status = mypiccinit_ntag(myctrlword,mypiccserial,mypickey,mypiccdata);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);mypcdbeep(30);QMessageBox::information(NULL, "提示","卡片初始化成功,卡号:"+uidstr );}else{disperrinf(status);}
}void MainWindow::on_pb_easy_read_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char myctrlword;         //写卡控制字unsigned char mypicdata[48];      //读卡数据缓冲unsigned char mypickey[4];        //卡片认证密码unsigned char blockadd;           //操作超始页地址unsigned char blocksize;          //操作页数if(ui->spinBox_num_rw->value()>12 || ui->spinBox_num_rw->value()<1){QMessageBox::critical(NULL, "提示","一次最多只能读12页!超过12页请分次读取。");return;}ui->lineEdit_uid->setText("");ui->plainTextEdit_data->setPlainText("");if(ui->checkbox_sele->isChecked()){     //选择先认证卡密码成功再读写卡QString authkey=ui->lineEdit_authkey->text().trimmed();if(authkey.length()==8 and checkinput(authkey)){for(int i=0;i<4;i++){bool ok;mypickey[i]=QString(authkey.mid(i*2,2)).toInt(&ok,16);}myctrlword=0x10;}else{QMessageBox::critical(NULL, "提示","请输入8位16进制认证密码!");ui->lineEdit_authkey->setFocus();return;}}else{myctrlword=0x00;    //无需认证卡密码}blockadd=ui->spinBox_star_rw->value();blocksize=ui->spinBox_num_rw->value();status = mypiccreadex_ntag(myctrlword, mypiccserial, mypickey, blockadd, blocksize, mypicdata);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);QString datastr="" ;for (int i = 0; i <  blocksize*4; i++) {datastr=datastr+QString::asprintf("%02X ",mypicdata[i]);}ui->plainTextEdit_data->setPlainText(datastr);mypcdbeep(30);QMessageBox::information(NULL, "提示","读卡成功,卡号:"+uidstr );}else{disperrinf(status);}
}void MainWindow::on_pb_easy_write_clicked()
{if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在unsigned char mypiccserial[7];    //卡唯一序列号uid缓冲unsigned char status;             //函数返回状态unsigned char myctrlword;         //写卡控制字unsigned char mypickey[4];        //卡片认证密码unsigned char blockadd;           //操作超始页地址unsigned char blocksize;          //操作页数if(ui->spinBox_num_rw->value()>11 || ui->spinBox_num_rw->value()<1){QMessageBox::critical(NULL, "提示","一次最多只能写11页!超过11页请分次写入。");return;}//检测写卡数据unsigned char piccdatabuf[255]; //写卡数据缓冲QChar ch;QString writinf = ui->plainTextEdit_data->toPlainText().trimmed();QString writinf1 = "";int m = 0;int n = 0;char s;if(writinf.length()<1){QMessageBox::critical(NULL, "提示", "请输入正确的16进制写卡数据!");ui->plainTextEdit_data->setFocus();return;}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){bool ok;piccdatabuf[m++] = writinf1.toInt(&ok,16);writinf1 = "";n = 0;if(m>=49){break;}}}else if(s == ' '){}else{QMessageBox::critical(NULL, "提示", "写卡数据错误,请输入正确的16进制数据!");ui->plainTextEdit_data->setFocus();return;}}ui->lineEdit_uid->setText("");if(ui->checkbox_sele->isChecked()){     //选择先认证卡密码成功再读写卡QString authkey=ui->lineEdit_authkey->text().trimmed();if(authkey.length()==8 and checkinput(authkey)){for(int i=0;i<4;i++){bool ok;mypickey[i]=QString(authkey.mid(i*2,2)).toInt(&ok,16);}myctrlword=0x10;}else{QMessageBox::critical(NULL, "提示","请输入8位16进制认证密码!");ui->lineEdit_authkey->setFocus();return;}}else{myctrlword=0x00;    //无需认证卡密码}blockadd=ui->spinBox_star_rw->value();blocksize=ui->spinBox_num_rw->value();status = mypiccwriteex_ntag(myctrlword, mypiccserial, mypickey, blockadd, blocksize, piccdatabuf);if(status==0){QString uidstr="" ;for (int i = 0; i < 7; i++) {uidstr=uidstr+QString::asprintf("%02X",mypiccserial[i]);}ui->lineEdit_uid->setText(uidstr);mypcdbeep(30);QMessageBox::information(NULL, "提示","写卡成功,卡号:"+uidstr );}else{disperrinf(status);}
}

相关文章:

Qt_C++读写NFC标签Ntag支持windows国产linux操作系统

本示例使用的发卡器&#xff1a;Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/智能海报/-淘宝网 (taobao.com) ntag2标签存储结构说明 #include "mainwindow.h" #include "./ui_mainwindow.h" #include <QDebug> #include "QLibrary&…...

Web开发-基础知识扫盲

目录 Web 服务器Web 服务器例子 MVC架构Web 项目运行过程负载均衡和反向代理持久化Java对象JPA Web 服务器 Web 服务器是一种计算机程序&#xff0c;它通过 HTTP 协议接收和响应客户端发送的请求。Web 服务器将 HTML、CSS、JavaScript 和其他资源文件发送给客户端&#xff0c;…...

SpringMVC 学习(四)RestFul 风格

5. RestFul 风格 5.1 简介 概念 Restful就是一个资源定位及资源操作的风格。不是标准也不是协议&#xff0c;只是一种风格。基于这个风格设计的软件可以更简洁&#xff0c;更有层次&#xff0c;更易于实现缓存等机制。 功能 资源&#xff1a;互联网所有的事物都可以被抽象为…...

消息中间件相关知识

1、概述 消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能&#xff0c;成为异步RPC的主要手段之一。当今市面上有很多主流的消息中间件&#xff0c;如老牌的ActiveMQ、RabbitMQ&#xff0c;炙手可热的Kafka…...

JackJson多态

JsonTypeInfo 处理多态、序列化对象类型_赵丙双的博客-CSDN博客 JsonTypeInfo实现jackson的多态解析_MonkeyKing_sunyuhua的博客-CSDN博客 Java Jackson JsonTypeInfo 多态类型处理 - 简书 JsonTypeInfo 逻辑名称 JsonSubTypes、JsonTypeName_赵丙双的博客-CSDN博客...

孟晚舟最新发声!华为吹响人工智能的号角,发布“全面智能化”战略部署

原创 | 文 BFT机器人 1、华为孟晚舟新发声&#xff0c;华为发布“全面智能化”战略 上周三&#xff08;9月30号&#xff09;上午&#xff0c;华为全联接大会2023正式在上海举行&#xff0c;作为华为副董事长、轮值董事长、CFO的孟晚舟代表华为再次发声&#xff01;在演讲上&am…...

open62541开发:添加sqlite3 历史数据库

历史数据库在OPCUA 应用中十分重要&#xff0c;例如OPCUA 网关和OPCUA 汇聚服务器中都需要历史数据库功能。但是open62541 协议栈中仅包含了基于内存的历史数据库&#xff0c;在实际应用中是不够的。本博文讨论open62541 中添加sqlite3 为基础的历史数据库若干问题。 借鉴 Gi…...

美国零售电商平台Target,值得入驻吗?如何入驻?

Target 是美国最大的零售商之一&#xff0c;在品牌出海为大势所趋的背景下&#xff0c;它在北美电商中的地位节节攀升。Target 商店在众多垂直领域提供各种价格实惠的自有品牌&#xff0c;吸引越来越多的跨境商家入驻&#xff0c;如美妆、家居、鞋服、日用百货等&#xff0c;随…...

docker freeswitch mysql驱动相关

1. docker环境 的freeswitch要连mysql数据库 2. centos版本&#xff1a;7.9 3. mysql版本&#xff1a;mysql8.0 4. odbc版本&#xff1a;适用以下命令查询 rpm -qa | grep -E "unixODBC|mysql-connector-odbc" mysql-connector-odbc-5.2.5-8.el7.x86_64 unixODB…...

Chrome iframe 跨域失败

原因&#xff1a; Chrome 稳定版禁用 document.domain setter 解决方案&#xff08;4种&#xff09;&#xff1a; 1 使用低版本Chrome 缺点&#xff1a;无法保证用户浏览器版本。 2 浏览器设置&#xff1a; 浏览器地址栏输入 chrome://flags/#origin-agent-cluster-default然…...

【Vue】vue-cli一站式搭建SPA项目

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Vue快速入门》。&#x1f3af;&#x1f3af; &…...

CPP代码检查工具

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言CPP代码检查工具工具一:GCC编译器工具二:Cppcheck工具三:gbd调试器工具四:SonarCube嵌入式平台工具内存泄漏检查工具linux的cpu占用情况前言 认…...

在SpringBoot中利用Redis实现互斥锁

在SpringBoot中利用Redis实现互斥锁 基本知识 前提条件&#xff0c;有一个能够在Springboot中使用Redis的项目&#xff0c;或者能够直接开也行 为什么要实现互斥锁&#xff1a;当我们利用Redis存储热点数据时&#xff0c;突然就过期失效或者被删除了&#xff0c;导致大量请求同…...

vue3+eleement plus日历选择季度

<template><div class"el-quarter-wrap"><el-popover width"280" v-model"visible"><template #reference><el-input v-model"quarterDate" placeholder"请选择季度" clearable :prefix-icon&qu…...

实现动态业务规则的方法(Java)

实现动态业务规则的方法&#xff08;Java&#xff09; 企业信息化系统核心在于业务领域的概念模型及于此基础上复杂多变的业务规则&#xff0c;实现中通常抽象规则的接口方法&#xff0c;使用继承或策略等设计模式实现不同的业务规则的实现。领域的概念模型在特定领域是稳定的…...

leetcodeTOP100(26)两数相加

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …...

performance_schema

插桩名称的最左边部分表示插桩类型&#xff0c;其余部分从左到右依次表示到特定的子系统 mysql> select * from performance_schema.setup_instruments where documentation is not null limit 5,5\G; *************************** 1. row ***************************NAME:…...

全新UI基于Thinkphp的最新自助打印系统/云打印小程序源码/附教程

这是一款全新的基于Thinkphp的最新自助打印系统&#xff0c;最新UI界面设计的云打印小程序源码&#xff0c;带有简单的教程。 下载地址&#xff1a;https://bbs.csdn.net/topics/617324130...

Android 13.0 framework层系统手势增加上滑手势home事件功能(相当于Home键)

1.概述 在13.0的定制化开发系统手势功能的时候,客户需求要求在上滑手势的时候,在底部上滑时候进入系统桌面,也就是增加 home键功能,所以就需要分析相关的系统手势上滑事件,然后添加home事件这样 就可以实现这个功能了 2.framework层系统手势增加上滑手势home事件功能的核…...

webp格式及其转成

"WebP" 是一种现代的图像压缩格式&#xff0c;由谷歌公司开发。它旨在提供高质量的图像压缩&#xff0c;同时减小图像文件的大小&#xff0c;从而加快网络加载速度。WebP 格式通常使用 ".webp" 扩展名来标识。 WebP 图像格式主要有以下几个特点和优点&…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...

Linux中INADDR_ANY详解

在Linux网络编程中&#xff0c;INADDR_ANY 是一个特殊的IPv4地址常量&#xff08;定义在 <netinet/in.h> 头文件中&#xff09;&#xff0c;用于表示绑定到所有可用网络接口的地址。它是服务器程序中的常见用法&#xff0c;允许套接字监听所有本地IP地址上的连接请求。 关…...

智警杯备赛--excel模块

数据透视与图表制作 创建步骤 创建 1.在Excel的插入或者数据标签页下找到数据透视表的按钮 2.将数据放进“请选择单元格区域“中&#xff0c;点击确定 这是最终结果&#xff0c;但是由于环境启不了&#xff0c;这里用的是自己的excel&#xff0c;真实的环境中的excel根据实训…...

Python_day48随机函数与广播机制

在继续讲解模块消融前&#xff0c;先补充几个之前没提的基础概念 尤其需要搞懂张量的维度、以及计算后的维度&#xff0c;这对于你未来理解复杂的网络至关重要 一、 随机张量的生成 在深度学习中经常需要随机生成一些张量&#xff0c;比如权重的初始化&#xff0c;或者计算输入…...

Asp.net Core 通过依赖注入的方式获取用户

思路&#xff1a;Web项目中&#xff0c;需要根据当前登陆的用户&#xff0c;查询当前用户所属的数据、添加并标识对象等。根据请求头Authorization 中token&#xff0c;获取Redis中存储的用户对象。 本做法需要完成 基于StackExchange.Redis 配置&#xff0c;参考&#xff1a;…...

C#调用Rust动态链接库DLL的案例

C#调用Rust动态链接库DLL的案例 项目概述 这是一个演示C#调用Rust动态链接库DLL的项目&#xff0c;包含&#xff1a; C#主程序 (Program.cs)Rust动态链接库 (rust_to_csharp目录) 使用C#创建一个net9的控制台项目&#xff0c;不使用顶级语句 dotnet new console --framewo…...