【一】验证码

验证码全称:captcha(全自动识别机器与人类的图灵测试),简单理解就是区分当前操作是人执行的还是机器执行的

常见验证码分3种:页面上图片形式、短信验证码(邮箱验证可以归类到短信验证码,只是载体不同。一个短信一个邮件)、语音验证码(点击后给手机打电话,机器读两遍验证码)。

注意:现在流行的刷脸是验证形式,不是验证码

(1)图片验证码

GD库是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片,也可以给图片加水印。

gd操作流程:①画布;②画干扰线、干扰点、生成验证码随机数画上去;③保存到session里;④输出图片

(2)验证码封装函数

在ThinkPHP里系统封装了验证码类:Verify.class.php,文件位置ThinkPHP/Library/Think/Verify.class.php

//存储在session里的验证码不是明文存储的,而是md5加密格式的。
//md5加密方式,不是之间加密,而是先连接seKey,截取其中多少位再md5加密:md5(123,seKey)
'seKey' => 'ThinkPHP.CN', // 验证码加密密钥
'codeSet'   =>  '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',             // 验证码字符集合
'expire'    =>  1800,            // 验证码过期时间(s)
'useZh'     =>  false,           // 使用中文验证码 
'zhSet'     =>  '们以我到他会作时要动国产的......'
'useImgBg'  =>  false,           // 使用背景图片,默认不使用,因为自带的TP背景图有点丑...
'fontSize'  =>  25,              // 验证码字体大小(px),默认25px有点大哦...
'useCurve'  =>  true,            // 是否画混淆曲线
'useNoise'  =>  true,            // 是否添加杂点
'imageH'    =>  0,               // 验证码图片高度
'imageW'    =>  0,               // 验证码图片宽度
'length'    =>  5,               // 验证码位数,默认5,一般图片是4个,手机验证码6个
'fontttf'   =>  '',              // 验证码字体,不设置则随机获取
'bg'        =>  array(243, 251, 254),  // 背景颜色
'reset'     =>  true,           // 验证成功后是否重置

①加密方式

具体加密流程在文件位置底部

/* 加密验证码 */
private function authcode($str){
$key = substr(md5($this->seKey), 5, 8);
$str = substr(md5($str), 8, 10);
return md5($key . $str);
}

这种二次加密的形式也叫加盐加密 / 加料加密,后期可能会用于数据表。

②验证码字符集

通过仔细观察验证码字符集可以发现少了许多字符,比如1,9l,g等。因为0和o,g和9等极其相似,所以为了避免频繁刷新验证码,减少服务器负担,所以将这些容易混淆的字符都去掉了

③验证码过期时间

因为验证码是存储在session中的,在规定的时间内若没有输入验证则会失效

④关于里面设置的字体、背景图,都在同级文件夹Verify中

⑤方法介绍

1. 构造方法:在实例化时可以传递一个数组,用于和其成员属性config合并,生成新配置

public function __construct($config=array()){
$this->config = array_merge($this->config, $config);
}

2. check方法:校验验证码,传递参数(用户输入的验证码)

/**
* 验证验证码是否正确
* @access public
* @param string $code 用户验证码
* @param string $id 验证码标识
* @return bool 用户验证码是否正确
*/
public function check($code, $id = '') {
$key = $this->authcode($this->seKey).$id;
// 验证码不能为空
$secode = session($key);
if(empty($code) || empty($secode)) {
return false;
}
// session 过期
if(NOW_TIME - $secode['verify_time'] > $this->expire) {
session($key, null);
return false;
} if($this->authcode(strtoupper($code)) == $secode['verify_code']) {
$this->reset && session($key, null);
return true;
} return false;
}

3. entry方法:输出验证码图片,并保存到session。通过header头输出,输出格式png

header('Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header("content-type: image/png");

4. 除了以上几个方法(配置、校验、输出),其他方法(例如加密验证码、绘制背景图、画杂点等)均为私密方法,不对外开放

(3)生成验证码

包含常规验证码和中文验证码

1. 常规验证码

由数字和大小写字母组成的验证码

注意:①验证码黑屏问题:输出前头部有Bom;②验证码字体控制一般用字体表4.ttf;

//生成常规验证码
public function yzm(){
ob_clean();
$array = array(
'fontSize' => 12, // 验证码字体大小(px)
'useCurve' => false, // 是否画混淆曲线
'useNoise' => false, // 是否添加杂点
'length' => 4, // 验证码位数
'fontttf' => '4.ttf', // 验证码字体,不设置随机获取
);
//1.实例化验证码类,两个方式①引入父类验证码use Think\Verify,写在namespace后;②行内形式\Think\Verify();
$verify = new \Think\Verify($array);
//2.输出验证码,之前说过对外有三个方法配置、校验、输出保存,这里应该调用输出方法
$verify->entry();
}

2. 中文验证码

注意:字体文件夹Verify下的中文字体文件夹zhttfs初始化时为空,所以无法和常规验证码一样直接使用。

字体文件可以在本地找到,控制面板---切换到大图标,找到字体--列出本地全部字体---复制黑体常规(中文即可)到中文文件夹zhttfs下。

//生成中文验证码
public function yzm(){
ob_clean();//去除Bom(编辑器加的UTF-8标签)
//配置
$cfg = array(
'useZh' => true, // 使用中文验证码
'fontSize' => 20, // 验证码字体大小(px)
'useCurve' => false, // 是否画混淆曲线
'useNoise' => false, // 是否添加杂点
'length' => 4, // 验证码位数
'fontttf' => '', // 验证码字体,不设置随机获取
);
//实例化验证码类
$Verify = new \Think\Verify($cfg);
//输出保存验证码图片
$Verify->entry();
}

补充说明:

①关于中文验证码:实际开发时,避免使用中文验证码(考虑外企合作);

②需要中文字体的支持,中文字体可以在本地找到或者网上下载复制到中文的文件夹下;

③使用中文验证码必须开启php_mbstring扩展(该扩展项在php.ini里,去掉扩展前的封号;即可,开启后重启Apache)

最新文章

  1. 《Entity Framework 6 Recipes》翻译系列 (5) -----第二章 实体数据建模基础之有载荷和无载荷的多对多关系建模
  2. MySQL初始化的正确姿势
  3. 四核RP4412开发板使用Xshell连接的com口应与电脑端口一致
  4. Session 类
  5. oracle重新启动步骤
  6. geom设置—条形图
  7. winform WebBrowser控件中,cs后台代码执行动态生成的js
  8. jsMath对象
  9. 简单的shell命令
  10. 深入理解JDBC的超时设置
  11. Solution of wireless link "PCI unknown" on Centos 7.1
  12. [DPDK] 转发 DPDK分析
  13. PyCharm的模板设置
  14. 手把手教你开发chrome扩展
  15. Java 中的接口
  16. Rails Guide -- Ruby on Rake(未详细阅读)
  17. 京东原来你运用的这玩意,不错,我也要!! ContainerDNS
  18. UTF-8, UTF-16, UTF-32 & BOM
  19. ADO.Net连接Oracle
  20. springboot 使用 mybatis + mapper

热门文章

  1. 编程算法 - 最小的k个数 代码(C)
  2. JAVA 学习 IDEA安装及破解
  3. tesnorflow Batch Normalization
  4. POJ 3281 Dining(最大流)
  5. JPA測试实例
  6. ASP.NET MVC Model之二模型绑定
  7. SYSUCPC2017 online round La La string 应用manacher算法
  8. bzoj4818
  9. 【148】DevExpress相关控件使用
  10. Ubuntu12.04安装JDK(jdk-6u45-linux-x64.bin)(转载)