Qt_C++读写M1IC卡源码支持windows国产linux操作系统

news2024/7/4 5:31:28

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

 IC卡的特性

1、分为16个扇区,每个扇区为4块,每块16个字节,以块为存取单位;
2、每个扇区有独立的一组密码及访问控制;
3、每张卡有唯一序列号,为32位;
4、具有防冲突机制,支持多卡操作;
5、无电源,自带天线,内含加密控制逻辑和通讯逻辑电路;
6、数据保存期为10年,可改写10万次,读无限次;
7、工作温度:-20℃~50℃(湿度为90%);
8、工作频率:13.56MHZ;
9、通信速率:106 KBPS;
10、读写距离:10 cm以内。 

 IC卡的存储结构

1、M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成,(我们也将16个扇区的64个块按绝对地址编号为0~63,存贮结构如下图所示: 

2、第0扇区的块0(即绝对地址0块),它用于存放厂商代码,已经固化,不可更改。

3、每个扇区的块0、块1、块2为数据块,可用于存贮数据。

4、每个扇区的块3为控制块,包括了密码A、存取控制、密码B;

5、每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。存取控制为4个字节,共32位,扇区中的每个块(包括数据块和控制块)的存取条件是由密码和存取控制共同决定的,在存取控制中每个块都有相应的三个控制位。 

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QDebug>
#include "QLibrary"
#include "QMessageBox"

#define BLOCK0_EN   0x01   //读写块0
#define BLOCK1_EN   0x02   //读写块1
#define BLOCK2_EN   0x04   //读写块2
#define NEEDSERIAL  0x08   //写指定序列号的卡
#define EXTERNKEY   0x10   //需要每次指定密码
#define NEEDHALT    0x20   //写卡后是否休眠卡


//让读写器发出声音
typedef  unsigned char (*pcdbeep)(unsigned long xms);
#ifdef Q_OS_WIN
    pcdbeep mypcdbeep = (pcdbeep)QLibrary("OUR_MIFARE.dll").resolve("pcdbeep");
#else
    pcdbeep mypcdbeep = (pcdbeep)QLibrary("./libOURIDR.so").resolve("pcdbeep");
#endif

//返回本读写器独一无二的设备编号
typedef  unsigned char (*pcdgetdevicenumber)(unsigned long devicenumber);
#ifdef Q_OS_WIN
    pcdgetdevicenumber mypcdgetdevicenumber = (pcdgetdevicenumber)QLibrary("OUR_MIFARE.dll").resolve("pcdgetdevicenumber");
#else
    pcdgetdevicenumber mypcdgetdevicenumber = (pcdgetdevicenumber)QLibrary("./libOURIDR.so").resolve("pcdgetdevicenumber");
#endif

//轻松读卡
typedef unsigned char (*piccreadex)(unsigned char ctrlword,unsigned char *serial,unsigned char area,unsigned char keyA1B0,unsigned char *picckey,unsigned char *piccdata0_2);
#ifdef Q_OS_WIN
    piccreadex mypiccreadex = (piccreadex)QLibrary("OUR_MIFARE.dll").resolve("piccreadex");
#else
    piccreadex mypiccreadex = (piccreadex)QLibrary("./libOURIDR.so").resolve("piccreadex");
#endif

//轻松写卡
typedef unsigned char (*piccwriteex)(unsigned char ctrlword,unsigned char *serial,unsigned char area, unsigned char keyA1B0,unsigned char *picckey,unsigned char *piccdata0_2);
#ifdef Q_OS_WIN
    piccwriteex mypiccwriteex = (piccwriteex)QLibrary("OUR_MIFARE.dll").resolve("piccwriteex");
#else
    piccwriteex mypiccwriteex = (piccwriteex)QLibrary("./libOURIDR.so").resolve("piccwriteex");
#endif

//改单区密码
typedef unsigned char (*piccchangesinglekeyex)(unsigned char ctrlword,unsigned char *serial,unsigned char area,unsigned char keyA1B0,unsigned char *piccoldkey,unsigned char *piccdata);
#ifdef Q_OS_WIN
    piccchangesinglekeyex mypiccchangesinglekeyex = (piccchangesinglekeyex)QLibrary("OUR_MIFARE.dll").resolve("piccchangesinglekeyex");
#else
    piccchangesinglekeyex mypiccchangesinglekeyex = (piccchangesinglekeyex)QLibrary("./libOURIDR.so").resolve("piccchangesinglekeyex");
#endif

//读出一块的数据,也就是16个字节
typedef unsigned char (*piccread)(unsigned char block,unsigned char *piccdata);
#ifdef Q_OS_WIN
    piccread mypiccread = (piccread)QLibrary("OUR_MIFARE.dll").resolve("piccread");
#else
    piccread mypiccread = (piccread)QLibrary("./libOURIDR.so").resolve("piccread");
#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_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("./libOURIDR.so");
    if (!mylib.load()){                //判断linux系统下,libOURIDR.so是否正运行目录内
        QMessageBox::information(NULL, "提示", "请将libOURIDR.so文件拷贝到生成的运行文件相同目录下!");
        return false;
    }else{return true;}
#endif
}


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->comboBox_2->setCurrentIndex(1);    
}


MainWindow::~MainWindow()
{
    delete ui;
}

//显示返回的错误代码信息
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;
    }
}


void MainWindow::on_pushButton_4_clicked()//让设备发出声响
{
    if(!checkdllos()){return;}

    unsigned char status;
    status = mypcdbeep(30);
    if(status==0){
    }
    else
    {
        disperrinf(status);
    }
}


void MainWindow::on_pushButton_3_clicked()//轻松读卡
{
    if(!checkdllos()){return;}

    unsigned char ctrlword;         //控制字
    unsigned char serial[4];        //可写数组,存放4字节卡UID
    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 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->currentIndex();           //操作扇区号
    keyA1B0 = ui->comboBox_2->currentIndex();      //密码认证类型,;大于0用A密码 ,等于0用B密码

    QString Key_str = ui->lineEdit->text().trimmed();
    if(Key_str.length()==12 and checkinput(Key_str)){
        for(int i=0;i<6;i++){
            bool ok;
            picckey[i]=QString(Key_str.mid(i*2,2)).toInt(&ok,16);
        }
        status = mypiccreadex(ctrlword,serial,area,keyA1B0,picckey,piccdata0_2);    //读取选定扇区的0、1、2块
        if(status == 0){
            QString blockdata="";
            for(int i=0;i<16;i++){
                blockdata=blockdata+QString::asprintf("%02X ", piccdata0_2[i]);
            }
            ui->lineEdit_2->setText(blockdata);
            blockdata="";
            for(int i=16;i<32;i++){
                blockdata=blockdata+QString::asprintf("%02X ", piccdata0_2[i]);
            }
            ui->lineEdit_3->setText(blockdata);
            blockdata="";
            for(int i=32;i<48;i++){
                blockdata=blockdata+QString::asprintf("%02X ", piccdata0_2[i]);
            }
            ui->lineEdit_4->setText(blockdata);

            status = mypiccread(area * 4 + 3,piccdata);   //读取选定扇区的第3块 A密码、控制位、B密码,无法读取的信息返回 00
            if(status == 0){
                blockdata="";
                for(int i=0;i<16;i++){
                    blockdata=blockdata+QString::asprintf("%02X ", piccdata[i]);
                }
                ui->lineEdit_5->setText(blockdata);
                mypcdbeep(30);
            }else{
                ui->lineEdit_5->clear();
                disperrinf(status);
            }

        }else{
            ui->lineEdit_2->clear();
            ui->lineEdit_3->clear();
            ui->lineEdit_4->clear();
            ui->lineEdit_5->clear();
            disperrinf(status);
        }
    }else{
        QMessageBox::critical(NULL, "提示","请输入12位16进制卡片认证密码!");
    }
}


void MainWindow::on_pushButton_12_clicked()//轻松写卡
{
    if(!checkdllos()){return;}

    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;          //返回
    char s;

    //以下控制字含义:读块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->currentIndex();           //操作扇区号
    keyA1B0 = ui->comboBox_2->currentIndex();      //密码认证类型,;大于0用A密码 ,等于0用B密码

    QString Key_str = ui->lineEdit->text().trimmed();
    if(Key_str.length()==12 and checkinput(Key_str)){
        for(int i=0;i<6;i++){
            bool ok;
            picckey[i]=QString(Key_str.mid(i*2,2)).toInt(&ok,16);
        }
    }else{
        QMessageBox::critical(NULL, "提示","请输入12位16进制卡片认证密码!");
        return;
    }

    //检测写卡数据
    QChar ch;
    QString writinf = ui->lineEdit_2->text().trimmed()+ui->lineEdit_3->text().trimmed()+ui->lineEdit_4->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){
                bool ok;
                piccdata0_2[m++] = writinf1.toInt(&ok,16);
                writinf1 = "";
                n = 0;
                if(m>=48){
                    break;
                }
            }
        }
        else if(s == ' '){

        }
        else
        {
            if(m>=0 && m<16){
                QMessageBox::critical(NULL, "提示", "第0块写卡数据错误,请输入正确的16进制数据!");
                ui->lineEdit_2->setSelection(m%16*3,2);
                ui->lineEdit_2->setFocus();
            }else if(m>=16 && m<32){
                QMessageBox::critical(NULL, "提示", "第1块写卡数据错误,请输入正确的16进制数据!");
                ui->lineEdit_3->setSelection(m%16*3,2);
                ui->lineEdit_3->setFocus();
            }else if(m>=32 && m<48){
                QMessageBox::critical(NULL, "提示", "第2块写卡数据错误,请输入正确的16进制数据!");
                ui->lineEdit_4->setSelection(m%16*3,2);
                ui->lineEdit_4->setFocus();
            }
            return;
        }
    }

    status = mypiccwriteex(ctrlword,serial,area,keyA1B0,picckey,piccdata0_2);
    if(status == 0)
    {
        mypcdbeep(30);
        QMessageBox::information(NULL, "提示", "写卡成功!");
    }else{
        disperrinf(status);
    }
}

//改AB密码及控制字
void MainWindow::on_pushButton_14_clicked()
{
    if(!checkdllos()){return;}

    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;       //返回

    //以下控制字含义:读块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->currentIndex();               //操作扇区号
    keyA1B0 = ui->comboBox_2->currentIndex();          //密码认证类型,;大于0用A密码 ,等于0用B密码

    QString Key_str = ui->lineEdit->text().trimmed();
    if(Key_str.length()==12 and checkinput(Key_str)){
        for(int i=0;i<6;i++){
            bool ok;
            piccoldkey[i]=QString(Key_str.mid(i*2,2)).toInt(&ok,16);
        }
    }else{
        QMessageBox::critical(NULL, "提示","请输入12位16进制卡片认证密码!");
        return;
    }

    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){
                bool ok;
                piccdata[m++] = writinf4.toInt(&ok,16);
                writinf4 = "";
                n = 0;
                if(m>=16){
                    break;
                }
            }
        }
        else if(s == ' ') {

        }
        else
        {
            QMessageBox::critical(NULL, "提示", "新A、B密码及控制位输入错误,请输入正确的16进制数据!");
            ui->lineEdit_5->setSelection(i,1);
            ui->lineEdit_5->setFocus();
            return;
        }
    }

    if(m<16)
    {
        QMessageBox::critical(NULL, "提示", "新A、B密码及控制位输入错误,请输入正确的16进制数据!");
        ui->lineEdit_5->setFocus();
        return;
    }

    piccdata[16]=0x03;   //取值0表示只改A密码,2表示改A、B密码,3表示修改A、B及控制位

    int answ=QMessageBox::question (this, "警告", "你确定修改密码控制块的数据吗 ?此数据块如果改写错误,数据卡将会被限制!", QMessageBox::Ok, QMessageBox::Cancel);
    if (answ ==1024){
        status = mypiccchangesinglekeyex(ctrlword,serial,area,keyA1B0,piccoldkey,piccdata);
        if(status == 0){
            mypcdbeep(30);
            QMessageBox::information(NULL, "提示", "操作成功,写卡数据有效!");
        }else {
            disperrinf(status);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/575745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HACK ME PLEASE: 1实战演练

文章目录 HACK ME PLEASE: 1实战演练一、前期准备1、相关信息 二、信息收集1、访问网站2、端口扫描2、扫描目录3、访问网站4、访问网站5、扫描目录6、访问网站7、登录MySQL数据库8、查看数据表9、查看users表的内容10、查看tblUsers表内容11、解密12、加密13、修改密码14、查询…

CentOS7.6(Linux)环境下有网和无网安装Docker

1、 服务器有网环境 1.1、手动卸载旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine1.2、安装yum-utils sudo yum install -y yum-utils \device-mapper-per…

项目并行管理指南:如何做好多项目管理?

多项目并行已经是大部分企业的现状&#xff0c;多项目并行同时进行已然是大部分企业的现状&#xff0c;同时管理多个项目是一件具有挑战性的&#xff0c;但是有一些方法和工具可以帮助我峨嵋你有条理地实施项目&#xff0c;提高效率&#xff0c;降低工作压力。 一&#xff0c;设…

【C++系列P4】模板搞不懂?脑阔抖三抖!!精讲一篇过!

前言 大家好吖&#xff0c;欢迎来到 YY 滴 C系列 &#xff0c;热烈欢迎&#xff01;本章主要内容面向接触过C的老铁&#xff0c;主要内容含 目录 一.模板 1.函数模板 一.函数模板概念 二.函数模板的格式 三.函数模板的实例化 1.隐式实例化 2.显式实例化 3.模板参数的…

多模态应用展望——看图聊天、BLIP2

看图聊天 BLIP2 是 salesforce 公司开源的多模态模型&#xff0c;其大致的原理&#xff0c;可以类比看图写作&#xff0c;当前 AI 在文生图模式之外&#xff0c;也支持图生文模式&#xff0c;可以将照片中的核心元素识别出来。然后把这些元素作为上下文&#xff0c;交给 ChatG…

MYSQL 8 中间字段有NULL 值,还是无法走索引,所以我高估了MYSQL 的查询智商

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

并查集(算法)

目录 一、并查集的概念二、并查集的使用合并集合连通块中点的数量食物链带权并查集扩展域并查集 一、并查集的概念 最裸并查集&#xff1a; 将两个集合合并。 询问两个元素是否在一个集合当中 &#xff0c;近乎 O ( 1 ) O(1) O(1) 时间内支持两个操作 基本原理&#xff1a…

chatgpt赋能python:Python文件大小:如何优化和管理您的文件大小

Python 文件大小&#xff1a;如何优化和管理您的文件大小 Python 是世界上最流行的编程语言之一&#xff0c;被广泛用于各种不同的应用程序。但是&#xff0c;随着项目变得越来越复杂&#xff0c;并且在需要处理大量数据的情况下&#xff0c;文件大小经常成为一个问题。因此&a…

数据包伪造、替换、劫持,https劫持之探索和测试

&#xff08;一&#xff09;数据包替换攻击 该攻击过程如下&#xff1a;伪造服务器响应客户端的数据包。监听客户端的数据包&#xff0c;用预先伪造的数据包&#xff0c;伪装成服务器返回的数据发送给客户端。 因为攻击者跟目标在同一个局域网&#xff0c;所以攻击者发送的数…

算法27:最长公共子序列——样本模型(4)

目录 简介 题目&#xff1a; 思路&#xff1a; 递归版本&#xff1a; 根据递归 分析推导 动态规划版本&#xff1a; 简介 前面刷了几道题目&#xff0c;都是从暴力递归到递归动态规划的版本&#xff0c;最后演变成纯动态规划的版本。接下来的题目&#xff0c;将会跳过 递…

chatgpt赋能python:Python找出列表中出现最多的元素

Python找出列表中出现最多的元素 介绍 在Python的编程过程中&#xff0c;经常需要处理列表&#xff0c;而处理列表时最常见的问题之一就是如何找出列表中出现最多的元素。在某些情况下&#xff0c;我们可能需要确定列表中重复出现最多的元素&#xff0c;并将其提取出来。Pyth…

[机器学习]线性回归

准备入门一下机器学习算法。 今天学习了线性回归&#xff0c;都是理论的东西&#xff0c;没有对于代码的实现&#xff0c;代码也会跟着进度好好搞一下。 对于线性回归的基础概念&#xff0c;我感觉很依靠概率论和线性代数两门课&#xff0c;作为刚准备完数学一考研的我&#xf…

Systrace系列12 —— CPU Info 解读

本文主要是对 Systrace 中的 CPU 信息区域(Kernel)进行简单介绍,简单介绍了如何在 Systrace 中查看 Kernel 模块输出的 CPU 相关的信息,了解 CPU 频率、调度、锁频、锁核相关的信息。 CPU 区域图例 下面是高通骁龙 845 手机 Systrace 对应的 Kernel 中的 CPU Info 区域(底下…

人工智能轨道交通行业周刊-第46期(2023.5.22-5.28)

本期关键词&#xff1a;数字孪生、AI铁路人、道岔、施封锁、图像质量评价、大模型小型化 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨道…

在VIVADO下烧写ZC706板载FLASH的操作步骤

1&#xff0c;原理图分析 首先看原理图&#xff0c;我们兼容ZC706的板子有两片 FLASH&#xff0c;型号是S25FL128A,连接方式如下&#xff1a; 可以看到两片是分别接在了XC7Z045芯片的引脚上&#xff0c;是互不相干的并联方式&#xff0c;每个FLASH芯片支持X4模式&#xff0c;也…

Systrace系列11 —— Triple Buffer 解读

本文主要是对 Systrace 中的 Triple Buffer 进行简单介绍,简单介绍了如何在 Systrace 中判断卡顿情况的发生,进行初步的定位和分析,以及介绍 Triple Buffer 的引入对性能的影响。 怎么定义掉帧? Systrace 中可以看到应用的掉帧情况,我们经常看到说主线程超过 16.6 ms 就会…

第一个Vue程序

什么是MVVM MVVM是Model-View-ViewModel的缩写&#xff0c;是一种软件架构模式&#xff0c;用于将用户界面&#xff08;UI&#xff09;的开发与业务逻辑和数据分离开来。 在MVVM架构中&#xff0c;Model代表数据模型层&#xff0c;View代表用户界面层&#xff0c;ViewModel充…

基于Java+控制台实现教材管理系统

基于Java控制台实现教材管理系统 一、系统介绍二、功能展示1.教材订购2.教材出售3.教材统计4.库存管理 四、其它1.其他系统实现2.获取源码 一、系统介绍 系统主要包括了教材订购、教材出售、教材统计、库存管理几大部分&#xff1b; 其中功能主要包括&#xff1a; 一、教材订购…

English Learning - L3 作业打卡 Lesson3 Day22 2023.5.26 周五

English Learning - L3 作业打卡 Lesson3 Day22 2023.5.26 周五 引言&#x1f349;句1: He would never pour salt on a wound, or make someone feel worse about something that was already a painful experience.成分划分弱读连读爆破语调 &#x1f349;句2: However, some…

字符串最后一个单词的长度

描述 计算字符串最后一个单词的长度&#xff0c;单词以空格隔开&#xff0c;字符串长度小于5000。&#xff08;注&#xff1a;字符串末尾不以空格为结尾&#xff09; 输入描述&#xff1a; 输入一行&#xff0c;代表要计算的字符串&#xff0c;非空&#xff0c;长度小于500…