0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

USB免驱IC读卡器QT小程序开发

邹振豪 来源:jf_51178285 2025-01-04 10:55 次阅读

经典USB免驱全协议IC卡读写器读取FM1208CPU卡。

FM1208CPU卡是一款由上海复旦微电子股份有限公司(Fudan Microelectronics Group, FMG)研发的高端智能非接触CPU卡芯片。以下是对该产品的详细介绍:

一、技术特点
1.先进工艺:FM1208采用先进的超深亚微米EEPROM工艺技术制造,具有高性能和稳定性。
大容量存储:该芯片拥有64K Byte EEPROM的存储容量,可以支持多种应用,如公交结算、小额支付等金融行业应用,实现一卡多种功能。
2.高安全性:芯片内置硬件DES协处理器,支持Triple-DES加密,提供比普通卡片更高的安全性。同时,芯片和卡片操作系统(COS)的协同安全技术为CPU卡提供了双重的安全保证,有效防止金融交易中的数据错误,保护消费者交易的私密性、安全性及个人利益。
3.广泛兼容性:FM1208符合ISO14443 Type A标准和ISO/IEC 7816-5规范,可以兼容现有的非接触逻辑加密卡,如市场上广泛应用的S50等,方便在已有应用下的升级和扩展。


二、功能与应用
功能强大:FM1208不仅具有数据存储功能,还具有命令处理、计算和数据加密等功能。其内置的卡片操作系统(COS)使得该芯片相当于一台微型计算机,可以根据实际应用情况灵活改变系统,满足客户的不同需求。
应用领域广泛:FM1208CPU卡广泛应用于城市公交、一卡通、高速公路卡、小额消费卡、校园卡、金融支付电子钱包、身份认证等领域。其高安全性、大容量和广泛兼容性使得该芯片在这些领域中具有显著的优势。


三、性能指标
通信协议:支持ISO 14443-A协议,工作频率为13.56MHz。
数据传输速率:支持高达106Kbps的数据传输速率。
程序存储器:32K x 8bit ROM。
数据存储器:8K x 8bit EEPROM,满足10万次擦写和10年数据保存指标。
内置RAM:256 x 8bit iRAM和384 x 8bit xRAM。
工作距离:不小于10CM。
识别时间:识别一张卡的时间约为3ms(包括复位应答和防冲突)。
EEPROM擦写时间:约为2.4ms。
典型交易过程:小于350ms。


四、市场应用与反馈
FM1208CPU卡已在多个城市大面积推广,如重庆的掌中行、合肥的一卡通等。特别是上海公共交通方面的试点,为非接触CPU卡在长江三角洲乃至全国的公交领域的应用推广起到了示范和推动作用。该产品的推出和应用,不仅提高了城市区域经济合作水平,还实现了城际间的互联互通,加强了城市间的联系。

综上所述,FM1208CPU卡凭借其先进的技术特点、广泛的应用领域以及卓越的性能指标,在智能卡市场中占据了重要地位。

QT小程序UI界面:

wKgZPGd190WAc959AADXyqHejNw472.png

QT小程序mainWindow.cpp代码:

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;
}
 
//检测输入数据是否为16进制数,将正确的16进制字符存入数组,并返回长度------------------------------------------------------------------------------------------------------------------------------------------------------------
static int checkhexdata(QString inputstr,unsigned char *databuf){
    QChar ch;
    QString writinf = inputstr.trimmed();
    QString writinf1 = "";
    int m = 0;
    int n = 0;
    char s;
 
    if(writinf.length()< 1){
        return -1;
    }
 
    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;
                databuf[m++] = writinf1.toInt(&ok,16);
                writinf1 = "";
                n = 0;
            }
        }
        else if(s == ' '){
 
        }
    }
    return m;
}
 
//检测动态库文件是否在运行目录内----------------------------------------------------------------------------------------------------------------------------------------------------------
static bool checkdllos(){
#ifdef Q_OS_WIN
    QLibrary mylib("OUR_MIFARE.dll");
    if (!mylib.load()){                //判断windows系统下,OUR_MIFARE.dll是否在运行目录内
        QMessageBox::information(NULL, "提示", "请将OUR_MIFARE.dll文件拷贝到生成exe文件相同目录下!");
        return false;
    }else{
        return true;
    }
#else
    QLibrary mylib("./libOURMIFARE.so");
    if (!mylib.load()){                //判断linux系统下,libOURMIFARE.so是否正运行目录内
        QMessageBox::information(NULL, "提示", "请将libOURMIFARE.so文件拷贝到生成的运行文件相同目录下!");
        return false;
    }else{return true;}
#endif
}
 
//显示返回的错误代码信息-----------------------------------------------------------------------------------------------------------------------------------------------------------------
static void disperrinf(unsigned char result){
    switch (result) {
    case 8:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",未寻到卡,请重新拿开卡后再放到感应区!");
        break;
    case 50:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",RATS错误,厂家调试代码,用户不需理会!");
        break;
    case 51:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",PPS错误,厂家调试代码,用户不需理会!");
        break;
    case 52:
        QMessageBox::information(NULL, "提示", QString::asprintf("代码:%d", result)+",已进入了14443-4协议状态,可进行CPU卡功能所有操作了!");
        break;
    case 53:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",CPU卡功能通讯错误!");
        break;
    case 54:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",数据不足,需要接着发送未完成的数据至卡上!");
        break;
    case 55:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",发送ACK指令给卡,让卡接着发送数据回来!");
        break;
    case 56:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",清空根目录失败!");
        break;
    case 57:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",卡片不支持此功能!");
        break;
    case 58:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",卡片初始化失败!");
        break;
    case 59:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",分配的空间不足!");
        break;
    case 60:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",本次操作的实体已存在!");
        break;
    case 61:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",无足够空间!");
        break;
    case 62:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",文件不存在!");
        break;
    case 63:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",权限不足,有可能是用只读密码认证,导致无法更改读写密码或无法写文件!");
        break;
    case 64:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",密码不存在,或密钥文件未创建!");
        break;
    case 65:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",传送长度错误!");
        break;
    case 66:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",Le错误,即接收的数据长度指定过大!");
        break;
    case 67:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",功能不支持或卡中无MF 或卡片已锁定!");
        break;
    case 68:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",密码认证错识次数过多,该密码已被锁死!");
        break;
    case 70:
    case 71:
    case 72:
    case 73:
    case 74:
    case 75:
    case 76:
    case 77:
    case 78:
    case 79:
    case 80:
    case 81:
    case 82:
    case 83:
    case 84:
    case 85:
        QMessageBox::critical(NULL, "提示", QString::asprintf("密码错误,剩余次数为:%d", result-70)+",如果为0,该密码将锁死,无法再认证!");
        break;
    case 86:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",更改后的密码长度必须和创建时的长度一致!");
        break;
    case 87:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",应用目录不存在!");
        break;
    case 88:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",应用文件不存在!");
        break;
    case 89:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",文件号不能超过5!");
        break;
    case 90:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",读取文件时返回的长度不足,数据可能不正确!");
        break;
    case 91:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",一次读文件的长度不能超过255!");
        break;
    case 92:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",一次写文件的长度不能超过247!");
        break;
    default:
        QMessageBox::critical(NULL, "提示", QString::asprintf("错误代码:%d", result)+",未知的错误信息!");
        break;
    }
}
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui- >setupUi(this);
 
    QPalette pa;
    pa.setColor(QPalette::WindowText,QColor(255, 0, 0));
    ui->label_7->setPalette(pa);
    ui->label_8->setPalette(pa);
    ui->label_9->setPalette(pa);
    ui->label_19->setPalette(pa);
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
 
void MainWindow::on_pb_beep_clicked()
{
    if(!checkdllos()){return;}      //判断运行目录内动态库文件是否存在
 
    unsigned char status;
    if (mypcdbeep != NULL){         //是否成功连接上 pcdbeep()函数
        status = mypcdbeep(30);
        if(status==0){
        }
        else
        {
            disperrinf(status);
        }
    } else{
        QMessageBox::critical(NULL, "提示", "函数‘pcdbeep’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_getdevnum_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char devicenumber[4];    //设备编号缓冲
    unsigned char status;             //函数返回状态
    if (mypcdgetdevicenumber != NULL){         //是否成功连接上 pcdgetdevicenumber()函数
        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);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘pcdgetdevicenumber’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_request_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char mypiccserial[4];    //卡序列号
    unsigned char myparam[4];         //参数
    unsigned char myver[1];           //版本
    unsigned char mycode[1];          //厂商代码(复旦为90)
    unsigned char status;             //函数返回状态
 
    if (mycpurequest != NULL){        //是否成功连接上 cpurequest()函数
        status = mycpurequest(mypiccserial,myparam,myver,mycode);
        if(status==0  || status==52){
            mypcdbeep(30);
            QString uidstr=QString::asprintf("%02X%02X%02X%02X", mypiccserial[0],mypiccserial[1],mypiccserial[2],mypiccserial[3]);
            QString parstr=QString::asprintf("%02X%02X%02X%02X", myparam[0],myparam[1],myparam[2],myparam[3]);
            QString verstr=QString::asprintf("%02X", myver[0]);
            QString codestr=QString::asprintf("%02X", mycode[0]);
 
            ui->lineEdit_uid->setText(uidstr);
            QMessageBox::information(NULL, "提示", "卡号:"+uidstr+",参数:"+parstr+",版本号:"+verstr+",厂商代码:"+codestr+" 的CPU卡已激活进入14443-4协议模式,可以继续以下的功能操作!");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpurequest’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_init_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char status;             //函数返回状态
    unsigned char ctrlword;           //是否先清空卡
    unsigned char mylen[1];           //密钥长度
    unsigned char keybuf[20];         //密钥
    int keylen;
    int spacesize;                    //空间大小
 
    if(ui->checkBox_clear->isChecked()){
        ctrlword=1;
    }else{ctrlword=0;}
 
    QString writinf = ui->lineEdit_cardkey->text().trimmed();
    keylen=checkhexdata(writinf,keybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制卡密码!");
        ui- >lineEdit_cardkey->setFocus();
        return;
    }
 
    mylen[0]=keylen;
    spacesize=ui->spinBox_maxsize->value();
 
    if (mycpursinit != NULL){        //是否成功连接上 cpursinit()函数
        status = mycpursinit(ctrlword,keybuf,mylen,spacesize);
        if(status==0 ){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "CPU卡初始化成功!");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpursinit’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
void MainWindow::on_pb_addeasyfile_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char status;             //函数返回状态
    unsigned char fileno;             //文件号
    unsigned char readkeylen[1];      //只读密钥长度
    unsigned char readkeybuf[20];     //只读密钥
    unsigned char rwkeylen[1];        //读写密钥长度
    unsigned char rwkeybuf[20];       //读写密钥
    int keylen;
    int spacesize;                    //空间大小
    QString keystr;
 
    fileno=ui->comboBox_addfile->currentIndex(); //新增加的文件号
 
    keystr = ui->lineEdit_readkey->text().trimmed();
    keylen=checkhexdata(keystr,readkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件只读密码!");
        ui- >lineEdit_readkey->setFocus();
        return;
    }
    readkeylen[0]=keylen;
 
    keystr = ui->lineEdit_rwkey->text().trimmed();
    keylen=checkhexdata(keystr,rwkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件读写密码!");
        ui- >lineEdit_rwkey->setFocus();
        return;
    }
    rwkeylen[0]=keylen;
 
    spacesize=ui->spinBox_2->value();
 
    if (mycpursfileadd_s != NULL){        //是否成功连接上 cpursfileadd_s()函数
        status = mycpursfileadd_s(fileno,readkeybuf,readkeylen,rwkeybuf,rwkeylen,spacesize);
        if(status==0 ){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "CPU卡创建易写文件成功,需要使用易写函数写入文件数据!");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpursfileadd_s’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
 
void MainWindow::on_pb_addfile_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char status;             //函数返回状态
    unsigned char fileno;             //文件号
    unsigned char readkeylen[1];      //只读密钥长度
    unsigned char readkeybuf[20];     //只读密钥
    unsigned char rwkeylen[1];        //读写密钥长度
    unsigned char rwkeybuf[20];       //读写密钥
    int keylen;
    int spacesize;                    //空间大小
    QString keystr;
 
    fileno=ui->comboBox_addfile->currentIndex();  //新增加的文件号
 
    keystr = ui->lineEdit_readkey->text().trimmed();
    keylen=checkhexdata(keystr,readkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件只读密码!");
        ui- >lineEdit_readkey->setFocus();
        return;
    }
    readkeylen[0]=keylen;
 
    keystr = ui->lineEdit_rwkey->text().trimmed();
    keylen=checkhexdata(keystr,rwkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件读写密码!");
        ui- >lineEdit_rwkey->setFocus();
        return;
    }
    rwkeylen[0]=keylen;
 
    spacesize=ui->spinBox_2->value();
 
    if (mycpursfileadd != NULL){        //是否成功连接上 cpursfileadd()函数
        status = mycpursfileadd(fileno,readkeybuf,readkeylen,rwkeybuf,rwkeylen,spacesize);
        if(status==0 ){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "CPU卡创建标准文件成功,需使用写标准文件函数写入数据!");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpursfileadd’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_changkey_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char status;             //函数返回状态
    unsigned char fileno;             //文件号
    unsigned char ctrlword;           //控制字
    unsigned char oldkeylen[1];       //旧密钥长度
    unsigned char oldkeybuf[20];      //旧密钥
    unsigned char newkeylen[1];       //新密钥长度
    unsigned char newkeybuf[20];      //新密钥
    int keylen;
    QString keystr;
 
    fileno=ui->comboBox_changekeyfile->currentIndex();  //要更改密钥的文件号
 
    if(ui->comboBox_changekey->currentIndex()==0){
        ctrlword=NEWKEYR;       //更改只读密码
    }else{ctrlword=NEWKEYWR;}   //更改读写密码
 
    if(ui->comboBox_authkey->currentIndex()==0){
        ctrlword=ctrlword+OLDKEYR;      //用只读密码来认证
    }else{ctrlword=ctrlword+OLDKEYWR;}  //用读写密码来认证
 
    keystr = ui->lineEdit_authkey->text().trimmed();
    keylen=checkhexdata(keystr,oldkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件认证密码!");
        ui- >lineEdit_authkey->setFocus();
        return;
    }
    oldkeylen[0]=keylen;
 
    keystr = ui->lineEdit_newkey->text().trimmed();
    keylen=checkhexdata(keystr,newkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件新密码!");
        ui- >lineEdit_newkey->setFocus();
        return;
    }
    newkeylen[0]=keylen;
 
    if (mycpursfilekeychg != NULL){        //是否成功连接上 cpursfilekeychg()函数
        status = mycpursfilekeychg(fileno,ctrlword,oldkeybuf,oldkeylen,newkeybuf,newkeylen);
        if(status==0 ){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "修改文件密码成功");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpursfilekeychg’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_read_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char status;             //函数返回状态
    unsigned char fileno;             //文件号
    unsigned char ctrlword;           //控制字
    unsigned char oldkeylen[1];       //旧密钥长度
    unsigned char oldkeybuf[20];      //旧密钥
    int staradd;                      //读写起始地址
    int datalen;                      //读写长度
    unsigned char rwbuf[8000];        //读写数据缓冲
    int keylen;
    QString keystr;
 
    fileno=ui->comboBox_rwfile->currentIndex();  //要读写的文件号
    staradd=ui->spinBox_rwbegin->value();        //读写起始地址
    datalen=ui->spinBox_rwlen->value();          //读写数据长度
    if(datalen< 1 || datalen >255){
        QMessageBox::critical(NULL, "提示", "每次读卡最多255字节,请输入正确的读卡长度!");
        ui->spinBox_rwlen->setFocus();
        return;
    }
 
    if(ui->comboBox_authrwkey->currentIndex()==0){
        ctrlword=OLDKEYR;      //用只读密码来认证
    }else{ctrlword=OLDKEYWR;}  //用读写密码来认证
 
    keystr = ui->lineEdit_authkey2->text().trimmed();
    keylen=checkhexdata(keystr,oldkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件认证密码!");
        ui- >lineEdit_authkey2->setFocus();
        return;
    }
    oldkeylen[0]=keylen;
 
    if (mycpursfiledataread != NULL){        //是否成功连接上 cpursfiledataread()函数
        status = mycpursfiledataread(fileno,ctrlword,oldkeybuf,oldkeylen,staradd,rwbuf,datalen);
        if(status==0 ){
            mypcdbeep(30);
            QString datastr="";
            for(int i=0;i< datalen;i++){
                datastr=datastr+QString::asprintf("%02X ", rwbuf[i]);
            }
            ui- >plainTextEdit->setPlainText(datastr);
 
            QMessageBox::information(NULL, "提示", "读取数据成功!");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpursfiledataread’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
 
void MainWindow::on_pb_write_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char status;             //函数返回状态
    unsigned char fileno;             //文件号
    unsigned char ctrlword;           //控制字
    unsigned char oldkeylen[1];       //旧密钥长度
    unsigned char oldkeybuf[20];      //旧密钥
    int staradd;                      //读写起始地址
    int datalen;                      //读写长度
    unsigned char rwbuf[8000];        //读写数据缓冲
    int keylen;
    QString keystr;
    QString datastr;
 
    keystr = ui->lineEdit_authkey2->text().trimmed();
    keylen=checkhexdata(keystr,oldkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件认证密码!");
        ui- >lineEdit_authkey2->setFocus();
        return;
    }
    oldkeylen[0]=keylen;
 
    datastr = ui->plainTextEdit->toPlainText().trimmed();
    datalen=checkhexdata(datastr,rwbuf);
    if(datalen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制写入数据!");
        ui- >plainTextEdit->setFocus();
        return;
    }
 
    fileno=ui->comboBox_rwfile->currentIndex();  //要读写的文件号
    staradd=ui->spinBox_rwbegin->value();        //读写起始地址
    datalen=ui->spinBox_rwlen->value();          //读写数据长度
    if(datalen< 1 || datalen >247){
        QMessageBox::critical(NULL, "提示", "每次写卡最多247字节,请输入正确的写卡长度!");
        ui->spinBox_rwlen->setFocus();
        return;
    }
 
    if(ui->comboBox_authrwkey->currentIndex()==0){
        ctrlword=OLDKEYR;      //用只读密码来认证
    }else{ctrlword=OLDKEYWR;}  //用读写密码来认证
 
    if (mycpursfiledatawrite != NULL){        //是否成功连接上 cpursfiledatawrite()函数
        status = mycpursfiledatawrite(fileno,ctrlword,oldkeybuf,oldkeylen,staradd,rwbuf,datalen);
        if(status==0 ){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "写入数据成功!");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpursfiledatawrite’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_easy_write_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char status;             //函数返回状态
    unsigned char fileno;             //文件号
    unsigned char ctrlword;           //控制字
    unsigned char oldkeylen[1];       //旧密钥长度
    unsigned char oldkeybuf[20];      //旧密钥
    int staradd;                      //读写起始地址
    int datalen;                      //读写长度
    unsigned char rwbuf[8000];        //读写数据缓冲
    int keylen;
    QString keystr;
    QString datastr;
 
    keystr = ui->lineEdit_authkey2->text().trimmed();
    keylen=checkhexdata(keystr,oldkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制文件认证密码!");
        ui- >lineEdit_authkey2->setFocus();
        return;
    }
    oldkeylen[0]=keylen;
 
    datastr = ui->plainTextEdit->toPlainText().trimmed();
    datalen=checkhexdata(datastr,rwbuf);
    if(datalen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制写入数据!");
        ui- >plainTextEdit->setFocus();
        return;
    }
 
    fileno=ui->comboBox_rwfile->currentIndex();  //要读写的文件号
    staradd=ui->spinBox_rwbegin->value();        //读写起始地址
    datalen=ui->spinBox_rwlen->value();          //读写数据长度
 
    if(ui->comboBox_authrwkey->currentIndex()==0){
        ctrlword=OLDKEYR;      //用只读密码来认证
    }else{ctrlword=OLDKEYWR;}  //用读写密码来认证
 
    if (mycpursfiledatawrite_s != NULL){        //是否成功连接上 cpursfiledatawrite_s()函数
        status = mycpursfiledatawrite_s(fileno,ctrlword,oldkeybuf,oldkeylen,staradd,rwbuf,datalen);
        if(status==0 ){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "写入数据成功!");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpursfiledatawrite_s’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_clear_clicked()
{
    if(!checkdllos()){return;}      //判断运行目录内动态库文件是否存在
 
    unsigned char status;
    if (mycpurscardclr != NULL){         //是否成功连接上 cpurscardclr()函数
        status = mycpurscardclr();
        if(status==0){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "cpu卡强制清空卡成功");
        }else{
            if(status==64){
                QMessageBox::information(NULL, "提示", "此卡为未经过我们cpursinit函数成功初始化的卡");
            }else{
                disperrinf(status);
            }
        }
    } else{
        QMessageBox::critical(NULL, "提示", "函数‘cpurscardclr’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_changecardkey_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char status;             //函数返回状态
    unsigned char oldkeylen[1];       //旧密钥长度
    unsigned char oldkeybuf[20];      //旧密钥
    unsigned char newkeylen[1];       //新密钥长度
    unsigned char newkeybuf[20];      //新密钥
    int keylen;
    QString keystr;
 
    keystr = ui->lineEdit_cardoldkey->text().trimmed();
    keylen=checkhexdata(keystr,oldkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制卡旧密码!");
        ui- >lineEdit_cardoldkey->setFocus();
        return;
    }
    oldkeylen[0]=keylen;
 
    keystr = ui->lineEdit_cardnewkey->text().trimmed();
    keylen=checkhexdata(keystr,newkeybuf);
    if(keylen< 0){
        QMessageBox::critical(NULL, "提示", "请输入正确的16进制卡新密码!");
        ui- >lineEdit_cardnewkey->setFocus();
        return;
    }
    newkeylen[0]=keylen;
 
    if (mycpurscardkeychg != NULL){        //是否成功连接上 cpurscardkeychg()函数
        status = mycpurscardkeychg(oldkeybuf,oldkeylen,newkeybuf,newkeylen);
        if(status==0 ){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "修改卡片密码成功");
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpurscardkeychg’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 
 
void MainWindow::on_pb_request1_clicked()
{
    if(!checkdllos()){return;}        //判断运行目录内动态库文件是否存在
 
    unsigned char mypiccserial[4];    //卡序列号
    unsigned char atqasakbuf[3];      //参数
    unsigned char status;             //函数返回状态
 
    if (mypiccrequest1 != NULL){        //是否成功连接上 cpurequest()函数
        status = mypiccrequest1(mypiccserial,atqasakbuf);
        if(status==0  || status==52){
            mypcdbeep(30);
            QString uidstr=QString::asprintf("%02X%02X%02X%02X", mypiccserial[0],mypiccserial[1],mypiccserial[2],mypiccserial[3]);
            QString atqastr=QString::asprintf("%02X%02X", atqasakbuf[0],atqasakbuf[1]);
            QString sakstr=QString::asprintf("%02X", atqasakbuf[2]);
 
            ui->lineEdit_uid->setText(uidstr);
            QMessageBox::information(NULL, "提示", "卡号:"+uidstr+",ATQA:"+atqastr+",SAK:"+sakstr);
        }
        else
        {
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示", "函数‘cpurequest’未正确载入,请查询DLL文件版本是否正确!");
    }
}
 

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • IC卡
    +关注

    关注

    2

    文章

    168

    浏览量

    34145
  • 读卡器
    +关注

    关注

    2

    文章

    417

    浏览量

    39385
  • EEPROM
    +关注

    关注

    9

    文章

    1022

    浏览量

    81663
  • 小程序
    +关注

    关注

    1

    文章

    238

    浏览量

    12159
收藏 人收藏

    评论

    相关推荐

    IC读卡器

    `IC读卡器型号:HBTZ---920本公司供应IC读卡器,品牌河北泰泽,型号HBTZ---920。质量保证,欢迎咨询洽谈。`
    发表于 09-18 15:24

    关于LABVIEW读取USB-RFID读卡器卡号问题

    有没有那位大神用LABVIEW程序读取过USB-RFID刷卡的(读取ID卡和IC卡2种读卡器,每刷一次读取里面的卡号数据)!!指教下。
    发表于 12-23 23:35

    电脑相关的读卡器

    读卡器是从卡形存储介质读取数据的数据输入设备。读卡器可根据不同类型的卡分为接触式和非接触式IC读卡器和远程读卡器。触点
    发表于 09-16 16:51

    关于USB读卡器的问题如何解决

    今天在测试USB读卡器这个例程,我把程序下载到开发板后,电脑检测可移动磁盘。但是我双击该移动磁盘,弹出“请将磁盘插入驱动G”请教原子大哥和
    发表于 06-17 04:20

    usb读卡器万能驱动下载

    usb读卡器万能驱动下载
    发表于 01-12 10:15 451次下载

    基于ARM的射频IC读卡器设计

    本文根据TCP/IP 网络中读卡器的访问需求,提出基于ARM 的射频IC读卡器的设计方案,并给出了详细的设计过程
    发表于 09-12 16:58 63次下载

    门禁系统非接触式IC读卡器的设计

    门禁系统非接触式IC读卡器的设计摘要: 非接触式IC读卡器是非接触式IC 卡技术应用的关键之一。文中给出了门禁系统非接触式
    发表于 05-30 17:03 435次下载

    支持可编程密集读卡器模式的RFID读卡器IC上市

    支持可编程密集读卡器模式的RFID读卡器IC上市 奥地利微电子公司(SWX 股票代码:AMS)今天推出AS3992,扩展了旗下面向Gen 2应用的、市场领先的UHF RFID读卡器
    发表于 12-16 09:33 1295次阅读
    支持可编程密集<b class='flag-5'>读卡器</b>模式的RFID<b class='flag-5'>读卡器</b><b class='flag-5'>IC</b>上市

    读卡器的接口类型

    读卡器的接口类型              接口类型是指读卡器与电脑主机之间的连接方式和类型。目前读卡器都是采用
    发表于 01-09 15:06 4413次阅读

    ID卡读卡器程序

    用51单片机设计的125kHZ完整C语言ID卡读卡器程序
    发表于 08-22 16:01 28次下载

    ID读卡器程序

    ID读卡器程序,感兴趣的小伙伴们可以瞧一瞧。
    发表于 11-05 14:48 21次下载

    基于STM32的USB读卡器的设计

    基于STM32的USB读卡器的设计
    发表于 09-25 11:11 29次下载
    基于STM32的<b class='flag-5'>USB</b><b class='flag-5'>读卡器</b>的设计

    usb3.0和usb2.0读卡器对比

    手里有个品胜的USB2.0读卡器,电脑配置更新之后带有3.0接口,所有买了个3.0的读卡器,选来选去感觉还是螃蟹芯片好些,入了一个“川宇C396”,之前有个老的8G内存卡。还有个前年买了一个威刚
    发表于 05-15 16:09 2.5w次阅读

    IC读卡器输出设置格式应用程序免费下载

    本文档的主要内容详细介绍的是IC读卡器输出设置格式应用程序免费下载。
    发表于 09-30 17:29 214次下载
    <b class='flag-5'>IC</b><b class='flag-5'>读卡器</b>输出设置格式应用<b class='flag-5'>程序</b>免费下载

    ID读卡器TCP协议QT程序开发

    ID卡网络读卡器TCP协议QT程序开发。 TCP(传输控制协议,Transmission Control Protocol)是互联网中最核心、最基本的协议之一。以下是对TCP协议的详
    的头像 发表于 12-31 10:19 83次阅读
    ID<b class='flag-5'>读卡器</b>TCP协议<b class='flag-5'>QT</b>小<b class='flag-5'>程序</b><b class='flag-5'>开发</b>