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

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(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 #include #include #include #include  class LoginDialog: public QDialog{    Q_OBJECTprivate:    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 #include #include #include #include   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(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(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 #include "LoginDialog.h"#include  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();}

 650) this.width=650;" src="https://s4.51cto.com/wyfs02/M01/8C/AC/wKioL1h0Z8bR8meBAABNlyr5C-Y949.png" title="图片1.png" alt="wKioL1h0Z8bR8meBAABNlyr5C-Y949.png" />

代码见附件

本文出自 “生命不息,奋斗不止” 博客,谢绝转载!

你可能感兴趣的:(QT开发)