首页 > 其他分享 >QT网盘笔记(日志,qss,加密)

QT网盘笔记(日志,qss,加密)

时间:2024-12-21 21:57:16浏览次数:6  
标签:__ char QT level int 网盘 qss Logger size

前言:

本章为本人在学习QT网盘时学到的知识,在此记录。

一、QT日志

1、前因

(1)网盘服务端需要记录每一个登陆者登录的时间,账号名,在遇到除操作错误的错误时候会统计到日志中,同时客户的意见反馈也写入其中。(2)加上互斥锁防止多线程写入时混乱。

2、互斥锁

       

(1)定义:在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。比如说,同一个文件,可能一个线程会对其进行写操作,而另一个线程需要对这个文件进行读操作,可想而知,如果写线程还没有写结束,而此时读线程开始了,或者读线程还没有读结束而写线程开始了,那么最终的结果显然会是混乱的。为了保护共享资源,在线程里也有这么一把锁——互斥锁(mutex),互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即上锁( lock )和解锁( unlock )。

(2)try_lock():如果互斥锁是未锁定状态,得到了互斥锁所有权并加锁成功,函数返回 true 如果互斥锁是锁定状态,无法得到互斥锁所有权加锁失败,函数返回 false。而lock() 函数用于给临界区加锁,并且只能有一个线程获得锁的所有权,它有阻塞线程的作用。二者的区别在于程 try_lock() 不会阻塞线程,lock() 会阻塞线程。

3、日志实现

运用中只需要用logInfo(//想记录的文字)(或其他)即log()函数

logger.h 

#ifndef LOGGER_H
#define LOGGER_H

#include <string>
#include <fstream>
#include <QMessageBox>
using namespace std;

#define logDebug(format)\
Logger::getinstance().log(Logger::DEBUG,__FILE__,__LINE__,format);//__FILE__与__LINE__是表示当前所在文件,行数的宏

#define logInfo(format)\
Logger::getinstance().log(Logger::INFO,__FILE__,__LINE__,format);

#define logHelp(format)\
Logger::getinstance().log(Logger::HELP,__FILE__,__LINE__,format);

#define logWarn(format)\
Logger::getinstance().log(Logger::WARN,__FILE__,__LINE__,format);

#define logError(format)\
Logger::getinstance().log(Logger::ERROR,__FILE__,__LINE__,format);



class Logger
{
public:
    enum Level
    {
        DEBUG = 0,
        INFO,
        HELP,
        WARN,
        ERROR,
        LEVEL_COUNT
    };
    static Logger& getinstance();
    void open(const string& filename);
    void foutClose();
    void log(Level level, const char* file, int line, const char* format);
    void level(Level level)
    {
        m_level = level;
    }
    void setMax(int bytes)
    {
        m_max = bytes;
    }

    Logger();
    ~Logger();
private:
    void rotate();
    string m_filename;
    ofstream m_fout;//输入流
    static const char* s_level[LEVEL_COUNT];
    Level m_level;
    int m_max;
    int m_len;
};

#endif // LOGGER_H

logger.cpp 

#include "logger.h"
#include <time.h>
#include <string.h>
#include <iostream>
#include <mutex>

using namespace std;

mutex log_mutex;

const char* Logger::s_level[LEVEL_COUNT] = {
    "DEBUG",
    "INFO",
    "HELP",
    "WARN",
    "ERROR",
};

Logger& Logger::getinstance()
{
    static Logger instance;
    return instance;
}

Logger::Logger():m_level(DEBUG),m_max(0),m_len(0)
{

}

Logger::~Logger()
{
    foutClose();
}

void Logger::open(const string& filename)
{
    m_fout.open(filename, ios::app);
    if (m_fout.fail())
    {
        QMessageBox::warning(NULL,"打开日志","打开日志失败");
    }
    m_fout.seekp(0, ios::end);
    m_len = m_fout.tellp(); //获取当前已写入的大小
}

void Logger::foutClose()
{
    m_fout.close();
}

void Logger::rotate()
{
    foutClose();
    time_t ticks = time(NULL);
    struct tm* ptm = localtime(&ticks);
    char timestamp[32];
    memset(timestamp, 0, sizeof(timestamp));
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", ptm);
    string filename = m_filename + timestamp;
    if (rename(m_filename.c_str(), filename.c_str()) != 0)
    {
        QMessageBox::warning(NULL,"更换新日志","更换新日志失败");
    }
    open(m_filename);
}

void Logger::log(Level level, const char* file, int line, const char* format)
{
    if (m_level > level)    //信息等级不到设置等级即不记录到日志中
    {
        return;
    }
    log_mutex.lock();   //上锁保证线程安全
    if (m_fout.fail())
    {
        QMessageBox::warning(NULL,"打开日志","打开日志失败");
    }
    time_t ticks= time(NULL);
    struct tm* ptm = localtime(&ticks);
    char timestamp[32];
    memset(timestamp, 0, sizeof(timestamp));
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", ptm);  //将时间戳转为字符形式的时间

    const char* fmt = "%s %s %s:%d ";
    int size = snprintf(NULL, 0, fmt, timestamp, s_level[level], file, line);
    if (size > 0)
    {
        char* buffer = new char[size + 1];
        snprintf(buffer, size + 1, fmt, timestamp, s_level[level], file, line); //整合信息
        buffer[size] = '\0';
        m_fout << buffer;  //将buffer信息存入日志中
        m_len += size;
        delete[] buffer;
    }
    size = snprintf(NULL,0,format);
    if (size > 0)
    {
        char* content = new char[size + 64];  //大小取大方便输入中文
        strcpy(content,format);
        m_len += size;
        m_fout << content;
    }
    m_fout <<"\n";
    m_fout.flush();//刷新缓冲,使内容写入磁盘

    if (m_len >= m_max && m_max > 0)
    {
        rotate();
    }
    log_mutex.unlock();
}

二、qss

1、前因

对每个控件定制样式和制作登录界面的时候用QPaintEvent不太方便,于是用QSS进行美化。

2、qss 文件样式:


控件名前加个 #代表指定某个控件;
border - image 表示填充整个背景;
background - image 表示设置背景,但不填充;
border 表示边框大小; 

border:none表示去掉边框
border - radius 表示边框圆角大小;
 

color 表示字体颜色;                                                                                                                  background-color表示背景颜色;                                                                                              background - position 表示图片位置;
background - repeat 表示图片是否重复显示;

三、加密

1、前因

将客户端输入的密码加密存储到数据库中既能防止传输过程中泄露由能防止数据库人员知晓客户密码。

2、凯撒密码

1、核心原理

其核心原理是通过将明文中的每个字母按照一定的规律进行替换,从而得到密文。这个规律通常是按照字母表顺序将每个字母移动固定的位数。

2、安全性低

(1)凯撒密码是一种非常简单的加密方式,因为总共只有 26 种可能的位移量(假设使用 26 个字母的英文字母表),其安全性较低。

(2)通过统计密文的字母频率也有可能破解密码。在大多数语言中,字母的出现频率是相对固定的(例如在英语中,字母 “e” 出现的频率最高),如果密文足够长,密码分析者可以根据这个频率特征来猜测位移量。

3、实现代码

#include <iostream>
#include <string>
using namespace std;
//加密
string encrypt(string plaintext, int key) {
    string ciphertext = "";
    for (char c : plaintext) {
        ciphertext += char(int(c) + key);
    }
    return ciphertext;
}
//解密
string decrypt(string ciphertext, int key) {
    string plaintext = "";
    for (char c : ciphertext)
    {
        plaintext += char(int(c) - key);
    }
    return plaintext;
}
int main() {
    string plaintext = "caixukun520";
    int key = 5;
    string encryptedtext = encrypt(plaintext, key);
    cout << encryptedtext <<endl;  //输出结果为: hfn}zpzs:75即为密文
    string decryptedtext =decrypt(encryptedtext,key);
    cout <<decryptedtext; //输出结果为caixukun520即为原来的密码
    return 0;
}

3、维吉尼亚密码

1、核心原理

维吉尼亚密码是在凯撒密码的基础上扩展而来的多表密码。与简单的单表代换密码(如凯撒密码)不同,维吉尼亚密码使用多个凯撒密码进行加密,密钥的长度决定了使用多少个不同的凯撒密码。
加密时,需要使用一个密钥词,这个密钥词由字母组成,长度可以任意。密钥词会重复使用,直到与明文长度相同(因为每个明文都要对应密匙加密)。

2、安全性

相较于凯撒密码安全性高上许多,但因为维吉尼亚密码的密钥是循环重复的,通过分析密文中相同字符组之间的距离,可以推测出密钥的长度(卡西斯基试验)。一旦确定了密钥长度,密文就能重新写成多列,列数与密钥长度对应。这样每一列其实就是一个凯撒密码从而破译。

3、实现代码

#include <iostream>
#include <string>
using namespace std;
char table[95][95];
char table1[95];
//方式一
void Init1()
{
    for (int i = 0; i < 95; i++)
    {
        table1[i] = 32 + i;//从字符空格开始,系统字符不能打印
    }
}
//加密

char* encrypt1(char* plaintext, char* key, int size)
{
    char* tempPlaintext = plaintext;
    char* tempKey = key;
    char* dest = new char[size];
    char* tempDest = dest;
    while (true)
    {
        *tempDest = table1[((*tempKey) - 32 + (*tempPlaintext) - 32) % 95];
        tempDest++;
        if (!(*(++tempKey)))
            tempKey = key;

        if (!(*(++tempPlaintext)))
            break;
    }
    dest[size - 1] = { '\0' };//添加结束符;
    return dest;
}
//方式二
void Init2()
{
    for (int i = 0; i < 95; i++)
    {
        for (int j = 0; j < 95; j++)
        {
            table[i][j] =32+(i+j) %95;  //从字符空格开始,系统字符不能打印
        }
    }
}
//加密
char* encrypt2(char* plaintext, char* key, int size) {
    char* tempPlaintext = plaintext;
    char* tempKey = key;
    char* dest = new char[size];
    char* tempdest = dest;
    while (1)
    {
        *tempdest = table[(*tempKey) - 32][(*tempPlaintext) - 32];
        tempdest++;
        if (!(*(++tempKey)))
            tempKey = key;

        if (!(*(++tempPlaintext)))
            break;
    }
    dest[size - 1] = { '\0' };//添加结束符;
    return dest;
}

//解密
char* decrypt(char* encryptedtext, char* key, int size)
{
    char* tempText = encryptedtext;
    char* tempKey = key;
    char* dest = new char[size];
    char* tempDest=dest;
    char c;
    while (true)
    {
        c = (*tempText-32) - (*tempKey-32);
        if (c < 0)
        {
            c = c + 95;//大于0说明没取模,直接相等,小于0则加上取掉的长度
        }
        *tempDest = 32 + c; //offset为在原表中的位置,应加上32
        tempDest++;

        if (!(*(++tempKey)))
            tempKey = key;

        if (!(*(++tempText)))
            break;
    }
    dest[size - 1] = { '\0' };//添加结束符;
    return dest;
    return dest;
}

int main() {
    Init1();
    Init2();

    string strPlaintext = "caixukun520";
    string strKey = "hajimi";
    char *caPlaintext=new char[strPlaintext.length() + 1];//方便自定义明文密码
    int size = strPlaintext.length() + 1;
    strcpy(caPlaintext,strPlaintext.c_str());
    char *caKey = new char[strKey.length() + 1];
    strcpy(caKey, strKey.c_str());
        
    char* encryptedtext1 = encrypt1(caPlaintext, caKey, size);
    char* encryptedtext2 = encrypt2(caPlaintext, caKey, size);
    cout << encryptedtext1 << endl;  //输出结果为: LCTbcU^P {}即为密文
    cout << encryptedtext2 << endl;  //输出结果一致
    char* decryptedtext=decrypt(encryptedtext1, caKey, size);
    cout << decryptedtext;  //输出结果为:caixukun520,解密成功

    return 0;
}

标签:__,char,QT,level,int,网盘,qss,Logger,size
From: https://blog.csdn.net/niairuochen/article/details/144546313

相关文章

  • 【Qt编程入门】
    目录【调试信息】【帮助文档】【项目结构】项目配置文件(.pro):用户文件(.user):主文件(main.cpp):头文件(.h):源文件(.cpp):【目录说明】构建目录:工作目录:【项目创建指南】特点:Qt在软件开发中的应用极为广泛:纯软件开发:Qt被广泛应用于开发各种桌面应用程序,如WPSOffice、暴......
  • pyqt5之GroupBox
    importsysfromPyQt5.QtWidgetsimportQApplication,QGroupBox,QVBoxLayout,QPushButton,QWidgetapp=QApplication(sys.argv)#创建一个QWidget作为主窗口main_widget=QWidget()#创建一个QGroupBoxgroupBox=QGroupBox("我的分组框")groupBox.setStyleS......
  • pyqt5文件对话框
    对话框选择文件#-*-coding:utf-8-*-#Formimplementationgeneratedfromreadinguifile'QFileDialog.ui'##Createdby:PyQt5UIcodegenerator5.15.9##WARNING:Anymanualchangesmadetothisfilewillbelostwhenpyuic5is#runagain.Do......
  • PyQt5与OpenCV结合的三个小练习
    题目1、简单图像处理创建一个PyQt应用程序,该应用程序能够:1、使用OpenCV加载一张图像。2、在PyQt的窗口中显示这张图像。3、提供四个按钮(QPushButton):一个用于将图像转换为灰度图一个用于将图像恢复为原始彩色图一个用于将图像进行翻转一个用于将图像进行旋转4、当用......
  • flutter 通过网络控制设备 emqx mqtt_client
    WiFi插件:mqtt_client:^10.5.1JWT加密:dart_jsonwebtoken:^2.14.1连接设备classWifiConnectVoid{staticvoidwifiConnectVoid({String?deviceModelId,String?deviceActivatedAt,String?deviceId,String?name,String?mod......
  • 没想到坚果云还能这样用,不止同步网盘!
    你的坚果云只是用来同步文件吗?同步只是最基础的一个功能,同步之后的高效文件管理、协同办公、移动办公才是效率提升的秘笈。今天,揭秘那些效率达人是如何玩转坚果云,释放性能,各行各业都有,绝对实用!1、情侣:爱就是同步,谈一场不分手的异地恋。异地恋情侣吵架分手,原因归根到底无外......
  • 全场景一站式2024最新vmware环境下安装win7并且破解QTP
    目录VMwareVMware和Ubuntu下载链接下载Win7系统各个操作系统网站激活码是什么查看是否激活激活操作vmware下安装ubuntu创建虚拟机下载VMtool灰色灰色按键点击不了下载提示有问题原因文件传递共享文件借助外界U盘有了VMTool就可以直接拖拽!!!!有了VMTool就可以全屏化——倒数第四个按......
  • 基于vgg16和efficientnet卷积神经网络的天气识别系统(pytorch框架) 图像识别与分类 前
    基于vgg16和efficientnet卷积神经网络的天气识别系统(pytorch框架)前端界面:flask+python,UI界面:pyqt5+python这是一个完整项目,包括代码,数据集,模型训练记录,前端界面,ui界面,各种指标图:包括准确率,精确率,召回率,F1值,损失曲线,准确率曲线等卷积模型采用vgg16模型或efficien......
  • 一款使用NET+MQTT+Arduino开发的智能浇花工具
    最近闲来无事,对硬件控制产生了兴趣。看到家里的盆栽,我突然萌生了制作一个自动浇水工具的想法。通过在淘宝搜索并查找相关资料,我了解了需要的硬件和通信协议。接下来,我们先看看需要做哪些准备工作(如安装Arduino、.NET、EMQX工具等,请自行搜索并完成安装)。准备工作硬件清单(淘......
  • Qt程序只能连接回环TCP Server服务端,无法连接其他IP的TCP Server服务端(已解决)
    .尝试解决无法连接下位TCP服务器的问题:(解决)在main函数中直接连接——》无效使用纸飞机客户端连接——》正常在main函数中连接纸飞机搭建的回环地址TCP服务——》成功在main函数中连接纸飞机搭建的192.166.100.200(以太网复用本机IP)——》失败新建Qt程序重试上面步......