共计 2054 个字符,预计需要花费 6 分钟才能阅读完成。
界面展示
核心概念
用户名和密码的获取
void QLoginDialog::onLoginBtnClicked()
{
if(m_captcha.toLower() == m_captchaEdit.text().toLower() )
{
m_user = m_userEdit.text().trimmed();
m_password = m_passwordEdit.text();
if(m_user != “” && m_password != “”)
{
done(QDialog::Accepted);
}
else
{
QMessageBox(QMessageBox::Critical, “ 错误 ”, “ 用户名或密码输入有误 ”, QMessageBox::Ok, this, Qt::Drawer).exec();
}
}
else
{
QMessageBox(QMessageBox::Critical, “ 错误 ”, “ 验证码输入有误 ”, QMessageBox::Ok, this, Qt::Drawer).exec();
qsrand(static_cast<uint>((QTime::currentTime().second() * 1000 + QTime::currentTime().msec())));
m_captcha = getCaptcha();
}
}
QString QLoginDialog::getUser()
{
return m_user;
}
QString QLoginDialog::getPassword()
{
return m_password;
}
随机验证码生成
需求
随机产生验证码
用户识别后填写
判断用户识别的正确性
可以有效避开恶意程序的识别
关于验证码和恶意程序
自动测试原理:
利用一些特殊的系统函数能够通过代码控制程序,从而模拟用户操作
恶意程序:
使用自动测试原理对目标程序进行控制,从而盗取信息或进行攻击
验证码:
随机产生,用户容易识别,程序难以识别,从而有效避免恶意攻击
注意的问题
验证码必须动态随机产生
验证码的显示避开使用标准组件(标签,文本框等)
验证码应该附带足够多的障碍增加程序识别难度
解决方案
随机产生目标验证码
将随机验证码直接绘制于登陆对话框(验证码中的每一个字符必须分开绘制)
验证码中的字符颜色随机改变
在验证码区域随机绘制噪点
关于随机数
计算机无法产生真正意义上的随机数
计算机只能模拟随机序列(伪随机数)
随机种子决定每次产生的随机序列是否相同(一般以时间戳作为随机种子)
/* 时间戳作为随机种子 */
qsrand(static_cast<uint>((QTime::currentTime().second() * 1000 + QTime::currentTime().msec())));
/**
* @brief 获取随机验证码
*/
QString QLoginDialog::getCaptcha()
{
QString ret = “”;
for(int i=0; i<4; i++)
{
int c = (qrand() % 2) ? ‘a’ : ‘A’;
ret += static_cast<QChar>(c + qrand() % 26);
}
return ret;
}
/**
* @brief 获取随机颜色值
*/
Qt::GlobalColor* QLoginDialog::getColor()
{
static Qt::GlobalColor color[4];
for(int i=0; i<4; i++)
{
color[i] = static_cast<Qt::GlobalColor>((2 + qrand() % 16));
}
return color;
}
/**
* @brief 定周期获取随机颜色值
* @brief 强制进行界面绘制
*/
void QLoginDialog::Timer_TimeOut()
{
m_colors = getColor();
update();
}
void QLoginDialog::paintEvent(QPaintEvent*)
{
QPainter painter(this);
painter.setFont(QFont(“consolas”, 12));
painter.fillRect(151, 67, 70, 20, Qt::white);
for(int i=0; i<150; i++) // 噪点绘制
{
painter.setPen(m_colors[i % 4]);
painter.drawPoint(151 + qrand() % 70, 67 + qrand() % 20);
}
for(int i=0; i<4; i++) // 验证码字符分开绘制
{
painter.setPen(m_colors[i]);
painter.drawText(151 + i*17, 67, 17, 20, Qt::AlignCenter, m_captcha.at(i));
}
}
验证码绘制:
总结
登陆对话框需要验证码验证机制避免恶意程序的破坏
验证码的产生需要随机数的支持(时间戳为随机种子)
验证码必须附带有效噪点
使用文本绘制的方式显示验证码,并且验证码的字符需要单度绘制
仓库
以上内容参考狄泰软件学院系列课程,请大家保护原创!