博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt4--加密日记本(子例化QMainWindow文本加密解密)
阅读量:6325 次
发布时间:2019-06-22

本文共 7157 字,大约阅读时间需要 23 分钟。

 

  • 近来刚学习Qt4编程,想找个实例练习练习,于是产生了一个想法,就是怎么样做一个文本加密,这样,自己保存的一些文档可以通过软件

 

生成加密文本,到时候要看的时候,通过自己的软件读取就可以。既然有想法了,那就行动起来吧!

 

  • 加密解密采用RC4方法,目前只能处理英文文档。
  • 首先介绍一下软件的框架
菜单栏:包括【file】、【edit】、【option】、【help】
  • 【file】下拉菜单包括【new】、【open】、【close】、【save】、【save as】、【exit】
  • 【edit】下拉菜单包括【copy】、【cut】、【paste】、【undo】、【redo】
  • 【option】下拉菜单包括【encrypt】、【decipher】
  • 【help】下拉菜单包括【about】
     
    
   
工具栏:包括【file】、【edit】、【option】、【font】、【list】
  • 【file】栏包括【new】、【open】、【save】、【save as】
  • 【edit】栏包括【copy】、【cut】、【paste】、【undo】、【redo】
  • 【option】栏包括【encrypt】、【decipher】
  • 【font】栏包括【fonttype】、【fontsize】、【bold】、【italic】、【under】、【color】
  • 【list】栏包括【list】、【left】、【center】、【justify】、【right】
编辑区:文本编辑框
状态栏:显示行列
  • 菜单栏的实现举例
菜单栏其实只是对功能函数的一个集合而已,拿【file】菜单举例,它包括【open】【new】【close】等操作,像【open】这样的操作,可以看做是一个函数的动作,
当我们点击这个选项的时候,执行相应的功能。
首先、在头文件中定义一个动作,然后为这个动作添加一个需要执行的槽
private slots:    void open();private:    QAction* openAction;
其次、就是在**.cpp中创建这个QAction
在这里为了各个QAction的创建和维护的便利性,我定义了一个creatAction()函数,如下是创建openAction的代码:
void SecretMainWindow::creatAction(){    //=========创建一个【file】->【Open】的动作响应=========//    openAction = new QAction(tr("&Open"), this);    openAction->setIcon(QIcon(":/images/open.png"));    openAction->setShortcut(QKeySequence::Open);    openAction->setStatusTip(tr("Open a file"));    connect(openAction, SIGNAL(triggered()), this, SLOT(open()));}
openAction = new QAction(tr("&Open"), this);
创建一个新的QAction,标签是【Open】
openAction->setIcon(QIcon(":/images/open.png"));
给【Open】设置一个图标
详见:
openAction->setShortcut(QKeySequence::Open);
给【Open】创建一个快捷键【Ctrl + O】
openAction->setStatusTip(tr("Open a file"));
给【Open】设置状态提示
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
连接信号与槽
然后、creatMenu()函数实现创建
void SecretMainWindow::creatMenus(){    //=========创建一个【file】菜单栏=========//    fileMenu = menuBar()->addMenu(tr("&File"));    fileMenu->addAction(newAction);    fileMenu->addAction(openAction);    fileMenu->addAction(closeAction);    fileMenu->addAction(saveAction);    fileMenu->addAction(saveAsAction);    fileMenu->addSeparator();    fileMenu->addAction(exitAction);}
fileMenu = menuBar()->addMenu(tr("&File"));
创建一个【file】菜单,并且命名为【File】
fileMenu->addAction(newAction);
添加【New】到菜单【File】
fileMenu->addSeparator();
添加一个分隔符
最后、实现槽函数open()
void SecretMainWindow::open(){    //========== 打开一个文件 ==========//    toSave();                                               //如果内容发生变更,执行保存    fileName = QFileDialog::getOpenFileName(this);          //获得要打开的文件的名字    if(!fileName.isEmpty())                                 //如果文件名不为空,加载文件    {        loadFile(fileName);    }    textEdit->setVisible(true);                         //文本编辑器可见}
  • 工具栏的实现举例
工具栏的实现分两种情况,一种是直接添加菜单栏里头的功能,另一种是只有工具栏上才有的一些功能,实现略有差异,下面分别举例说明。
情况一:把菜单栏里功能添加到工具栏,如【open】
void SecretMainWindow::creatToolBars(){    //=========创建一个【file】工具栏=========//    fileToolBar = addToolBar(tr("&File"));    fileToolBar->addAction(newAction);    fileToolBar->addAction(openAction);    fileToolBar->addSeparator();    fileToolBar->addAction(saveAction);    fileToolBar->addAction(saveAsAction);}
方法与建立【file】菜单类似。需要在头文件里建立一个工具栏的变量
QToolBar* fileToolBar;
其余创建过程与【file】菜单是一致的。
情况二:创建工具栏特有的功能,如字体Font
//=========创建一个【font】工具栏=========//    fontToolBar = addToolBar(tr("&Font"));    fontstyleLabel = new QLabel(tr("FontType:"));    fontBox = new QFontComboBox;    fontBox->setFontFilters(QFontComboBox::ScalableFonts);    fontToolBar->addWidget(fontstyleLabel);    fontToolBar->addWidget(fontBox);
fontToolBar = addToolBar(tr("&Font"));
在工具栏上添加一个设置字体的工具栏
fontstyleLabel = new QLabel(tr("FontType:"));
新建一个标签:【FontType】
fontBox = new QFontComboBox;
新建一个字体下拉框
fontBox->setFontFilters(QFontComboBox::ScalableFonts);
把字体添加到下拉框
fontToolBar->addWidget(fontstyleLabel);    fontToolBar->addWidget(fontBox);
把标签和下拉框添加到工具栏上
  • 更新状态栏
void SecretMainWindow::creatStatusBar(){    locationLabel = new QLabel;    locationLabel->setAlignment(Qt::AlignHCenter);    locationLabel->setMinimumSize(locationLabel->sizeHint());    statusBar()->addWidget(locationLabel);    connect(textEdit, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar()));    updateStatusBar();}void SecretMainWindow::updateStatusBar(){    locationLabel->setText(tr("%1 row  %2 col").arg(textEdit->document()->blockCount())                           .arg(textEdit->textCursor().columnNumber()));}
statusBar()->addWidget(locationLabel);
把状态栏标签添加到状态栏上
connect(textEdit, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar()));
当光标位置发生变化的时候,触发更新状态栏
locationLabel->setText(tr("%1 row  %2 col").arg(textEdit->document()->blockCount())                           .arg(textEdit->textCursor().columnNumber()));
显示出光标的位置,其中1,2分别对应后面的两个参数
  • 加密解密
void SecretMainWindow::encrypt(){    //save();    //QFile file(currentFile);    //QTextStream in(&file);    QString text;    text.append(textEdit->toPlainText());    passwordDlg = new PassWord(this);    if(passwordDlg->exec())    {        if(!passwordDlg->password.isNull())            RC4(text, passwordDlg->password);    }}
text.append(textEdit->toPlainText());
获取编辑区的文档内容
passwordDlg = new PassWord(this);
新建一个弹出窗口,输入加密密钥
passwordDlg->exec()
运行弹出窗口
if(!passwordDlg->password.isNull())            RC4(text, passwordDlg->password);
确定获取到密钥后,进行RC4加密,参考网上的程序。
void SecretMainWindow::RC4(QString in, QString key){    int inLen = in.length();    unsigned char* sequence;    sequence = (unsigned char*)qstrdup(in.toAscii().constData());    int keyLen = key.length();    unsigned char* cKey;    cKey = (unsigned char*)qstrdup(key.toAscii().constData());    QString out = "";    //Init Sbox    char SBox[128],Key[128];    int i, k, j = 0, t;    char temp, r;    for(i = 0; i < 128; i++)        SBox[i] = i;    for(k = i = 0; i < 128; i++)    {        Key[i] = cKey[k];        k = (k + 1) % keyLen;    }    for (i = 0; i < 128; i++)    {        j = (j + SBox[i] + Key[i]) % 128;        temp = SBox[i];        SBox[i] = SBox[j];        SBox[j] = temp;    }    //RC4 Cipher    i=0;    j=0;    for(k = 0; k < inLen; k++)    {        r = sequence[k];        i = (i + 1) % 128;        j = (j + SBox[i]) % 128;        temp = SBox[i];        SBox[i] = SBox[j];        SBox[j] = temp;        t = (SBox[i] + SBox[j]) % 128;        r = r ^ SBox[t];        //out += QString::number(r, 16);        out += QString(QChar(r));        //char rr = char(r);        //out += QString::fromUtf8(&rr);    }    textEdit->clear();    textEdit->setText(out);    delete[] sequence;}
其中,解密就是加密的逆过程,因此可以用同一个函数解密。
void SecretMainWindow::decipher(){    encrypt();}
  • 弹出密钥输入窗口
创建一个password类。
#ifndef PASSWORD_H#define PASSWORD_H#include
class QLabel;class QPushButton;class QLineEdit;class PassWord:public QDialog{ Q_OBJECTpublic: PassWord(QWidget* parent = 0); QString password;private: QLabel* passwordLabel; QLineEdit* passwordLineEdit; QPushButton* okButton; QPushButton* cancelButton;private slots: void slotOk(); void slotCancel();//signals: //getPassword(const QString& password);};#endif // PASSWORD_H
点击【ok】,获取密码,点击【Cancel】取消操作。
void PassWord::slotOk(){    password = passwordLineEdit->text();    //emit getPassword(password);    this->accept();}void PassWord::slotCancel(){    password = QString::null;    this->reject();}
  • 效果演示
加密前:
加密后:
  • 程序下载
用VS2008编译,发布release版本

 

 

你可能感兴趣的文章
shell脚本路径写法的注意点
查看>>
Testng生成的测试报告乱码解决办法
查看>>
vim快速入门
查看>>
大杂烩 -- 单向链表是否存在环或是否相交
查看>>
java中重载与重写的区别
查看>>
mybatis mapper xml文件配置resultmap时,id行和result行有什么区别?
查看>>
关键字检索高亮标出-javasript/jQuery代码实现
查看>>
Vijos P1785 同学排序【模拟】
查看>>
人物关系网络图可视化
查看>>
关于ADO.Net SqlConnection的性能优化
查看>>
docker安装及加速配置
查看>>
MRF能量优化
查看>>
CNN卷积核反传分析
查看>>
UWP Xaml设计器中输入特殊字符
查看>>
关系型数据库工作原理-数据结构(3)
查看>>
Linux学习笔记
查看>>
open-falcon监控Flume
查看>>
netstat Recv-Q和Send-Q
查看>>
《红黑树》学习心得
查看>>
Lazarus安装使用
查看>>