界面展示
核心概念
用户名和密码的获取
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));
}
}
验证码绘制:
总结
- 登陆对话框需要验证码验证机制避免恶意程序的破坏
- 验证码的产生需要随机数的支持(时间戳为随机种子)
- 验证码必须附带有效噪点
- 使用文本绘制的方式显示验证码,并且验证码的字符需要单度绘制
以上内容参考狄泰软件学院系列课程,请大家保护原创!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。