一个简单安全的PHP验证码类、PHP验证码


Posted in PHP onSeptember 24, 2016

一,验证码示例

一个简单安全的PHP验证码类、PHP验证码

二,php验证码类,secoder.class.php

<?php 
/** 
* 安全验证码 
* 
* 安全的验证码要:验证码文字扭曲、旋转,使用不同字体,添加干扰码 
* 
* @author 流水孟春 <cmpan(at)qq.com> 
* @link http://labs.yulans.cn/YL_Security_Secoder 
* @link http://wiki.yulans.cn/docs/yl/security/secoder 
*/ 
class YL_Security_Secoder { 
/** 
* 验证码的session的下标 
* 
* @var string 
*/ 
//public static $seKey = 'sid.sek ey.ylans.cn'; 
public static $seKey = 'sid'; 
public static $expire = 3000; // 验证码过期时间(s) 
/** 
* 验证码中使用的字符,01IO容易混淆,建议不用 
* 
* @var string 
*/ 
public static $codeSet = '346789ABCDEFGHJKLMNPQRTUVWXY'; 
public static $fontSize = 25; // 验证码字体大小(px) 
public static $useCurve = true; // 是否画混淆曲线 
public static $useNoise = true; // 是否添加杂点 
public static $imageH = 0; // 验证码图片宽 
public static $imageL = 0; // 验证码图片长 
public static $length = 4; // 验证码位数 
public static $bg = array(243, 251, 254); // 背景 
protected static $_image = null; // 验证码图片实例 
protected static $_color = null; // 验证码字体颜色 
/** 
* 输出验证码并把验证码的值保存的session中 
* 验证码保存到session的格式为: $_SESSION[self::$seKey] = array('code' => '验证码值', 'time' => '验证码创建时间'); 
*/ 
public static function entry() { 
// 图片宽(px) 
self::$imageL || self::$imageL = self::$length * self::$fontSize * 1.5 + self::$fontSize*1.5; 
// 图片高(px) 
self::$imageH || self::$imageH = self::$fontSize * 2; 
// 建立一幅 self::$imageL x self::$imageH 的图像 
self::$_image = imagecreate(self::$imageL, self::$imageH); 
// 设置背景 
imagecolorallocate(self::$_image, self::$bg[0], self::$bg[1], self::$bg[2]); 
// 验证码字体随机颜色 
self::$_color = imagecolorallocate(self::$_image, mt_rand(1,120), mt_rand(1,120), mt_rand(1,120)); 
// 验证码使用随机字体 
//$ttf = dirname(__FILE__) . '/ttfs/' . mt_rand(1, 20) . '.ttf'; 4 
$ttf = dirname(__FILE__) . '/ttfs/4.ttf'; 
if (self::$useNoise) { 
// 绘杂点 
self::_writeNoise(); 
} 
if (self::$useCurve) { 
// 绘干扰线 
self::_writeCurve(); 
} 
// 绘验证码 
$code = array(); // 验证码 
$codeNX = 0; // 验证码第N个字符的左边距 
for ($i = 0; $i<self::$length; $i++) { 
$code[$i] = self::$codeSet[mt_rand(0, 27)]; 
$codeNX += mt_rand(self::$fontSize*1.2, self::$fontSize*1.6); 
// 写一个验证码字符 
imagettftext(self::$_image, self::$fontSize, mt_rand(-40, 70), $codeNX, self::$fontSize*1.5, self::$_color, $ttf, $code[$i]); 
} 
// 保存验证码 
isset($_SESSION) || session_start(); 
$_SESSION[self::$seKey]['code'] = join('', $code); // 把校验码保存到session 
$_SESSION[self::$seKey]['time'] = time(); // 验证码创建时间 
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"); 
// 输出图像 
imagepng(self::$_image); 
imagedestroy(self::$_image); 
} 
/** 
* 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数) 
* 
* 高中的数学公式咋都忘了涅,写出来 
* 正弦型函数解析式:y=Asin(ωx+φ)+b 
* 各常数值对函数图像的影响: 
* A:决定峰值(即纵向拉伸压缩的倍数) 
* b:表示波形在Y轴的位置关系或纵向移动距离(上加下减) 
* φ:决定波形与X轴位置关系或横向移动距离(左加右减) 
* ω:决定周期(最小正周期T=2π/?ω?) 
* 
*/ 
protected static function _writeCurve() { 
$A = mt_rand(1, self::$imageH/2); // 振幅 
$b = mt_rand(-self::$imageH/4, self::$imageH/4); // Y轴方向偏移量 
$f = mt_rand(-self::$imageH/4, self::$imageH/4); // X轴方向偏移量 
$T = mt_rand(self::$imageH*1.5, self::$imageL*2); // 周期 
$w = (2* M_PI)/$T; 
$px1 = 0; // 曲线横坐标起始位置 
$px2 = mt_rand(self::$imageL/2, self::$imageL * 0.667); // 曲线横坐标结束位置 
for ($px=$px1; $px<=$px2; $px=$px+ 0.9) { 
if ($w!=0) { 
$py = $A * sin($w*$px + $f)+ $b + self::$imageH/2; // y = Asin(ωx+φ) + b 
$i = (int) ((self::$fontSize - 6)/4); 
while ($i > 0) { 
imagesetpixel(self::$_image, $px + $i, $py + $i, self::$_color); // 这里画像素点比imagettftext和imagestring性能要好很多 
$i--; 
} 
} 
} 
$A = mt_rand(1, self::$imageH/2); // 振幅 
$f = mt_rand(-self::$imageH/4, self::$imageH/4); // X轴方向偏移量 
$T = mt_rand(self::$imageH*1.5, self::$imageL*2); // 周期 
$w = (2* M_PI)/$T; 
$b = $py - $A * sin($w*$px + $f) - self::$imageH/2; 
$px1 = $px2; 
$px2 = self::$imageL; 
for ($px=$px1; $px<=$px2; $px=$px+ 0.9) { 
if ($w!=0) { 
$py = $A * sin($w*$px + $f)+ $b + self::$imageH/2; // y = Asin(ωx+φ) + b 
$i = (int) ((self::$fontSize - 8)/4); 
while ($i > 0) { 
imagesetpixel(self::$_image, $px + $i, $py + $i, self::$_color); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多 
$i--; 
} 
} 
} 
} 
/** 
* 画杂点 
* 往图片上写不同颜色的字母或数字 
*/ 
protected static function _writeNoise() { 
for($i = 0; $i < 10; $i++){ 
//杂点颜色 
$noiseColor = imagecolorallocate( 
self::$_image, 
mt_rand(150,225), 
mt_rand(150,225), 
mt_rand(150,225) 
); 
for($j = 0; $j < 5; $j++) { 
// 绘杂点 
imagestring( 
self::$_image, 
5, 
mt_rand(-10, self::$imageL), 
mt_rand(-10, self::$imageH), 
self::$codeSet[mt_rand(0, 27)], // 杂点文本为随机的字母或数字 
$noiseColor 
); 
} 
} 
} 
/** 
* 验证验证码是否正确 
* 
* @param string $code 用户验证码 
* @param bool 用户验证码是否正确 
*/ 
public static function check($code) { 
isset($_SESSION) || session_start(); 
// 验证码不能为空 
if(empty($code) || empty($_SESSION[self::$seKey])) { 
//echo $_SESSION[self::$seKey]['code'].'1'; 
return false; 
} 
// session 过期 
if(time() - $_SESSION[self::$seKey]['time'] > self::$expire) { 
unset($_SESSION[self::$seKey]); 
//echo $_SESSION[self::$seKey]['code'].'2'; 
return false; 
//return 0; 
} 
// if($code == $_SESSION[self::$seKey]['code']) { 
if(strtoupper($code) == $_SESSION[self::$seKey]['code']) { //不区分大小写比较 
//echo $_SESSION[self::$seKey]['code'].'3'; 
return true; 
} 
//echo $_SESSION[self::$seKey]['code'].'4'; 
return false; 
} 
} 
// useage 
/* 
YL_Security_Secoder::$useNoise = false; // 要更安全的话改成true 
YL_Security_Secoder::$useCurve = true; 
YL_Security_Secoder::entry(); 
*/ 
/* 
// 验证验证码 
if (!YL_Security_Secoder::check(@$_POST['secode'])) { 
print 'error secode'; 
} 
*/

三,调用方法

1,显示验证码页面code.php

<?php 
session_start(); 
require 'secoder.class.php'; //先把类包含进来,实际路径根据实际情况进行修改。 
$vcode = new YL_Security_Secoder(); //实例化一个对象 
$vcode->entry(); 
?>

2,检查验证码是否正确

<?php 
session_start(); 
require 'secoder.class.php'; //先把类包含进来,实际路径根据实际情况进行修改。 
$vcode = new YL_Security_Secoder(); //实例化一个对象 
//$vcode->entry(); 
$code = $_GET['code']; 
echo $vcode->check($code); 
//$_SESSION['code'] = $vc->getCode();//验证码保存到SESSION中 
?>

3,验证码输入框调用页面

<img id="messageImg" src='images/tishis2.gif' width='16' height='16'> 单击图片重新获取验证码<br> 
<a href="#"><img src="code.php" onclick="javascript:this.src='code.php?tm='+Math.random();" />

以上所述是小编给大家介绍的一个简单安全的PHP验证码类、PHP验证码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
PHP session会话的安全性分析
Sep 08 PHP
PHP中数字检测is_numeric与ctype_digit的区别介绍
Oct 04 PHP
简单的php文件上传(实例)
Oct 27 PHP
PHP Warning: Module 'modulename' already loaded in问题解决办法
Mar 16 PHP
php设计模式之单例模式代码
Jun 11 PHP
PHP 将数组打乱 shuffle函数的用法及简单实例
Jun 17 PHP
php实现压缩合并js的方法【附demo源码下载】
Sep 22 PHP
php获取flash尺寸详细数据的方法
Nov 12 PHP
laravel5.4生成验证码的实例讲解
Aug 05 PHP
使用PHP连接数据库_实现用户数据的增删改查的整体操作示例
Sep 01 PHP
Laravel5.5以下版本中如何自定义日志行为详解
Aug 01 PHP
php微信公众号开发之秒杀
Oct 20 PHP
jquery不支持toggle()高(新)版本的问题解决
Sep 24 #PHP
php getcwd与dirname(__FILE__)区别详解
Sep 24 #PHP
mysql desc(DESCRIBE)命令实例讲解
Sep 24 #PHP
mysql alter table命令修改表结构实例详解
Sep 24 #PHP
Ajax和PHP正则表达式验证表单及验证码
Sep 24 #PHP
mysql查找删除重复数据并只保留一条实例详解
Sep 24 #PHP
php源码 fsockopen获取网页内容实例详解
Sep 24 #PHP
You might like
如何使用PHP往windows中添加用户
2006/12/06 PHP
php实现专业获取网站SEO信息类实例
2015/04/02 PHP
php源码分析之DZX1.5随机数函数random用法
2015/06/17 PHP
Laravel 中使用 Vue.js 实现基于 Ajax 的表单提交错误验证操作
2017/06/30 PHP
Yii2框架配置文件(Application属性)与调试技巧实例分析
2019/05/27 PHP
基于jquery的固定表头和列头的代码
2012/05/03 Javascript
详解JavaScript函数绑定
2013/08/18 Javascript
js有序数组的连接问题
2013/10/01 Javascript
自写的jQuery异步加载数据添加事件
2014/05/15 Javascript
JQuery 控制内容长度超出规定长度显示省略号
2014/05/23 Javascript
JavaScript设计模式之观察者模式(发布者-订阅者模式)
2014/09/24 Javascript
EasyUI实现二级页面的内容勾选的方法
2015/03/01 Javascript
jQuery实现带滑动条的菜单效果代码
2015/08/26 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
2016/01/27 Javascript
JavaScript实现瀑布流以及加载效果
2017/02/11 Javascript
JavaScript 中调用 Kotlin 方法实例详解
2017/06/09 Javascript
Bootstrap datepicker日期选择器插件使用详解
2017/07/26 Javascript
利用JS hash制作单页Web应用的方法详解
2017/10/10 Javascript
python命令行参数解析OptionParser类用法实例
2014/10/09 Python
两个使用Python脚本操作文件的小示例分享
2015/08/27 Python
如何将python中的List转化成dictionary
2016/08/15 Python
python3解析库lxml的安装与基本使用
2018/06/27 Python
python3获取控制台输入的数据的具体实例
2020/08/16 Python
在 Python 中使用 MQTT的方法
2020/08/18 Python
python中count函数知识点浅析
2020/12/17 Python
Python操作PostgreSql数据库的方法(基本的增删改查)
2020/12/29 Python
详解使用scrapy进行模拟登陆三种方式
2021/02/21 Python
html5的自定义data-*属性与jquery的data()方法的使用
2014/07/02 HTML / CSS
中国跨镜手机配件批发在线商店:TVC-Mall
2019/08/20 全球购物
Lookfantastic阿联酋官网:英国知名美妆护肤购物网站
2020/05/26 全球购物
迪士尼法国在线商店:shopDisney FR
2020/12/03 全球购物
酒店拾金不昧表扬信
2014/01/18 职场文书
企业办公室岗位职责
2014/03/12 职场文书
2014校长四风问题对照检查材料思想汇报
2014/09/16 职场文书
公司出差管理制度范本
2015/08/05 职场文书
高中生物教学反思
2016/02/20 职场文书