QT开发(六十六)——登录对话框的验证机制

一、验证码机制

为了避免被恶意程序***,程序通常要使用安全机制。验证码机制是提供产生随机验证码,由用户识别填写来判断用户有效性的安全机制。

验证码必须动态随机产生,验证码的显示必须避开使用标准组件(如标签、文本框等),同时要增加足够的障碍难度增加程序的识别难度。

基本的解决方案如下:

A、随机产生目标验证码

B、将验证码直接绘制于登录对话框

C、验证码中的字符颜色随机变化

D、在验证码区域随机绘制噪点

二、登录对话框验证码机制实现

1、随机数产生

计算机只能产生伪随机数。

QString getRandom()
{QString ret = "";for(int i=0; i<4; i++){int c = (qrand() % 2) ? 'a' : 'A';ret += static_cast<QChar>(c + qrand() % 26);}return ret;
}

2、验证码绘制

每次绘制单个验证码,使用随机颜色的画笔

for(int i = 0; i < 4; i++){painter.setPen(m_colors[i]);painter.drawText(245 + 25*i, 150, 25, 30, Qt::AlignCenter, QString(m_verification[i]));}

3、噪点绘制

在验证码绘制矩形区域内随机位置绘制噪点

for(int i=0; i<150; i++){painter.setPen(m_colors[i%4]);painter.drawPoint(245 + qrand() % 99, 150 + qrand() % 29);}

4、代码实例

LoginDialog.h文件:

#ifndef LOGINDIALOG_H
#define LOGINDIALOG_H#include <QDialog>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QTimer>class LoginDialog: public QDialog
{Q_OBJECT
private:QLabel UserLabel;QLabel PwdLabel;QLabel Verification;QLineEdit VerificationEdit;QLineEdit UserEdit;QLineEdit PwdEdit;QPushButton B_Login;QPushButton B_Cancel;QString m_user;QString m_pwd;Qt::GlobalColor* m_colors;QString m_verification;QTimer m_timer;
private:Qt::GlobalColor* getColors();QString getVerificationCode();void paintEvent(QPaintEvent *event);void mouseDoubleClickEvent(QMouseEvent *event);private slots:void Login();void Cancel();void onTimeOut();public:LoginDialog(QWidget *parent);QString getUser();QString getPwd();~LoginDialog();
};#endif // LOGINDIALOG_H

LoginDialog.cpp文件:

#include "LoginDialog.h"
#include <QDebug>
#include <QMessageBox>
#include <QPainter>
#include <QMouseEvent>
#include <QTime>LoginDialog::LoginDialog(QWidget *parent):QDialog(parent, Qt::WindowCloseButtonHint), UserLabel(this), PwdLabel(this),Verification(this),VerificationEdit(this), UserEdit(this), PwdEdit(this), B_Login(this),B_Cancel(this)
{UserLabel.setText("User ID:");UserLabel.move(50, 50);UserLabel.resize(60, 30);UserEdit.move(110, 50);UserEdit.resize(200, 30);PwdLabel.setText("Password:");PwdLabel.move(50, 100);PwdLabel.resize(60,30);PwdEdit.move(110, 100);PwdEdit.resize(200, 30);PwdEdit.setEchoMode(QLineEdit::Password);Verification.move(50, 150);Verification.resize(110, 30);Verification.setText("Verification Code: ");VerificationEdit.move(160, 150);VerificationEdit.resize(80, 30);B_Login.setText("Login");B_Login.move(110, 200);B_Login.resize(80, 30);B_Cancel.setText("Cancel");B_Cancel.move(230, 200);B_Cancel.resize(80, 30);setWindowTitle("Login Window");setFixedSize(400, 300);//生成伪随机种子qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());m_colors = getColors();m_verification = getVerificationCode();connect(&B_Login, SIGNAL(clicked()), this, SLOT(Login()));connect(&B_Cancel, SIGNAL(clicked()), this, SLOT(Cancel()));connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeOut()));m_timer.start(500);
}void LoginDialog::onTimeOut()
{qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());m_colors = getColors();update();
}QString LoginDialog::getUser()
{return m_user;
}QString LoginDialog::getPwd()
{return m_pwd;
}void LoginDialog::Login()
{qDebug() << "login";QString verif = VerificationEdit.text().replace(" ", "");if(m_verification.toLower() == verif.toLower()){m_user = UserEdit.text().trimmed();m_pwd = PwdEdit.text();if(!(m_user.isEmpty() || m_pwd.isEmpty())){done(Accepted);}else{QMessageBox mb(this);mb.setWindowTitle("Warning Message");mb.setIcon(QMessageBox ::Warning);mb.setText("User or PassWord can't empty! \nPlease check your username or password!");mb.setStandardButtons(QMessageBox::Ok);mb.exec();}}else{QMessageBox::critical(this, "Verification Code Error", "Verification Code Error!\nPlease Enter Again.", QMessageBox::Ok);VerificationEdit.selectAll();}
}void LoginDialog::Cancel()
{qDebug() << "cancel";done(Rejected);}void LoginDialog::paintEvent(QPaintEvent *event)
{QPainter painter(this);//填充验证码绘制矩形painter.fillRect(245, 150, 100, 30, Qt::white);painter.setFont(QFont("Comic Sans MS", 12));//绘制验证码for(int i = 0; i < 4; i++){painter.setPen(m_colors[i]);painter.drawText(245 + 25*i, 150, 25, 30, Qt::AlignCenter, QString(m_verification[i]));}//绘制噪点for(int i=0; i<150; i++){painter.setPen(m_colors[i%4]);painter.drawPoint(245 + qrand() % 99, 150 + qrand() % 29);}
}Qt::GlobalColor* LoginDialog::getColors()
{static Qt::GlobalColor colors[4];for(int i=0; i<4; i++){colors[i] = static_cast<Qt::GlobalColor>(2 + qrand() % 16);}return colors;
}
//获取验证码
QString LoginDialog::getVerificationCode()
{QString ret = "";for(int i = 0; i < 4; i++){int c = (qrand() % 2) ? 'a' : 'A';ret += static_cast<QChar>(c + qrand() % 26);}return ret;
}
//双击验证码绘制矩形区域,生成新的验证码
void LoginDialog::mouseDoubleClickEvent(QMouseEvent *event)
{if(QRect(245, 150, 100, 30).contains(event->pos())){m_verification = getVerificationCode();repaint();}
}LoginDialog::~LoginDialog()
{
}

Main.cpp文件:

#include "Widget.h"
#include <QApplication>
#include "LoginDialog.h"
#include <QDebug>int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget w;LoginDialog dialog(&w);dialog.show();if(dialog.exec() == QDialog::Accepted){qDebug() <<"User:" << dialog.getUser();qDebug() << "PassWord:" << dialog.getPwd();}return a.exec();
}

代码见附件

转载于:https://blog.51cto.com/9291927/1890686

QT开发(六十六)——登录对话框的验证机制相关推荐

  1. 【正点原子STM32连载】第六十六章 综合测试实验摘自【正点原子】STM32F103 战舰开发指南V1.2

    1)实验平台:正点原子stm32f103战舰开发板V4 2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420 3)全套实验源码+手册+视 ...

  2. web工作流管理系统开发之十六 主子流程参数传递的实现

    在设计流程的时候,如果涉及到子流程,就会有主子流程间传递参数的过程. 例如,将主流程的执行人,传递给子流程,子流程根据主流程的执行人不同,会有不同的处理方式: 又例如,采购流程中,卖方备货处理时,发现 ...

  3. S3C2416裸机开发系列十六_sd卡驱动实现

    S3C2416裸机开发系列十六 sd卡驱动实现 象棋小子    1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.数据传输快.可插拔.安全性好等优 ...

  4. Qt OpenGL(三十六)——Qt OpenGL 核心模式-绘制雷达坐标系

    提示:本系列文章的索引目录在下面文章的链接里(点击下面可以跳转查看): Qt OpenGL 核心模式版本文章目录 Qt OpenGL(三十六)--Qt OpenGL 核心模式-绘制雷达坐标系 一.场景 ...

  5. QT开发(十)——QT输入组件

    QT开发(十)--QT输入组件 QT中有十三中输入组件,分别是下拉列表框QComboBox.字体下拉框QFontComboBox.行编辑框QLineEdit.文本编辑框QTextEdit.无格式文本编 ...

  6. 如何选择适合你的兴趣爱好(六十六),折纸

    围城网的摇摇今天给大家带来了"如何选择适合你的兴趣爱好"系列专辑的第六十六讲--折纸. 折纸又称工艺折纸,是一种以纸张折成各种不同形状的手工活动.话说我在大三的时候,爱上了系里的一 ...

  7. 第六十六章 SQL命令 REVOKE

    文章目录 第六十六章 SQL命令 REVOKE 大纲 参数 描述 撤销的角色 撤销对象权限 撤销对象所有者特权 撤销表级和列级特权 CASCADE 或 RESTRICT 对缓存查询的影响 IRIS S ...

  8. 人生哲理名言六十六条

    一提到哲理好像是老年人的专利,其实年青人多看看和学学哲理也是有好处的.摘录哲理名言共享. 人生哲理名言六十六条: 1人之所以痛苦,在于追求错误的东西. 2如果你不给自己烦恼,别人也永远不可能给你烦恼. ...

  9. JavaScript学习(六十六)—字符串对象常用的属性和方法总结以及数组元素的排序问题

    JavaScript学习(六十六)-字符串对象常用的属性和方法总结以及数组元素的排序问题 学习内容 一.数组去重问题 二.二维数组的定义 三.二维数组的元素操作 四.二维数组的遍历 五.关联数组 六. ...

最新文章

  1. Python将Pandas中Dataframe数据保存为gzip/zip文件:gzip压缩文件、zip压缩文件
  2. 字符串转数字 sql_SQL注入·sqli-labs·基于错误的字符串/数字型注入(第1~2关)
  3. qt 中 设置 背景的方法
  4. Java Web使用数据库连接池
  5. OpenCV k均值聚类kmeans clustering的实例(附完整代码)
  6. JAVA中在某游戏系统有猫狗猪_算法面试题之猫狗队列(java)
  7. 为什么envi镶嵌老是出错_10个数学考试老出错的根源和解决办法,你值得拥有
  8. 用R语言实现密度聚类dbscan
  9. 4.企业安全建设入门(基于开源软件打造企业网络安全) --- 威胁情报
  10. pycharm编程工具自带python环境_Python IDE专用编辑器PyCharm下载及配置安装过程(Ubuntu环境)...
  11. ​十大骨传导耳机品牌,骨传导耳机推荐跑步用
  12. 手机怎么看php格式的视频教程,wmv格式用手机怎么看
  13. 【编程语言】PHP完全自学手册
  14. WPS vbe6ex.olb 不能加载
  15. 以TFP401A为核心的DVI接口应用系统
  16. LSTM结构理解与python实现
  17. 编程中等于号的不同含义
  18. 田纳西大学计算机科学,田纳西大学
  19. 程序员2天做出的猫咪情绪识别软件,究竟用了什么技术?
  20. zzuli 20级第六次周赛 2733 问题 K: 键盘霸主hrs

热门文章

  1. python用字典编写购物程序_Python编写购物小程序
  2. 浏览器阻挡cookies_解决WordPress登录提示”Cookies被阻止或者您的浏览器不支持”...
  3. mac电脑循环次数多少算新_ARM架构电脑之路,苹果需要从微软Surface ProX中吸取哪些教训?...
  4. c语言行计数程序,C语言非常简单的字符统计程序50行
  5. alert不会影响到页面中其他代码执行_JavaScript调试技巧合集——为什么不推荐使用alert调试代码?...
  6. 生物类似药产业发展策略及项目投资建设报告2021-2027年
  7. 中国食品检测行业市场发展策略及投资战略建议报告2022-2028年版
  8. DBUtils (30)
  9. BZOJ3224普通平衡树
  10. git fatal: 拒绝合并无关的历史