zoukankan      html  css  js  c++  java
  • 修改ThinkPHP的验证码类

      今天用ThinkPHP重新开发一个系统,用到了ThinkPHP的验证码类,由于我希望验证码别太复杂,希望验证码里边只有数字,却发现该Verify类并未提供设置验证码中使用的字符的配置的方法,于是查看源码,觉得这个类功能还是不够齐全,所以修改了一点点,让用户可以配置验证码中使用的字符的范围。

      1 <?php
      2 // +----------------------------------------------------------------------
      3 // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
      4 // +----------------------------------------------------------------------
      5 // | Copyright (c) 2006-2013 http://thinkphp.cn All rights reserved.
      6 // +----------------------------------------------------------------------
      7 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
      8 // +----------------------------------------------------------------------
      9 // | Author: Knight <S.Knight.Work@gmail.com> <http://www.getyourwant.com>
     10 // +----------------------------------------------------------------------
     11 // | Commet: 原作者:麦当苗儿 增加了验证码中使用的字符的配置,用户可以配置
     12 // | 验证码中使用的字符的范围
     13 // +----------------------------------------------------------------------
     14 
     15 namespace Think;
     16 
     17 class Verify {
     18     protected $config =    array(
     19         'seKey'     => 'ThinkPHP.CN',   //验证码加密密钥
     20         'expire'    => 1800,            // 验证码过期时间(s)
     21         'useZh'     => false,           // 使用中文验证码 
     22         'useImgBg'  => false,           // 使用背景图片 
     23         'fontSize'  => 25,              // 验证码字体大小(px)
     24         'useCurve'  => true,            // 是否画混淆曲线
     25         'useNoise'  => true,            // 是否添加杂点    
     26         'imageH'    => 0,               // 验证码图片高度
     27         'imageW'    => 0,               // 验证码图片宽度
     28         'length'    => 5,               // 验证码位数
     29         'fontttf'   => '',              // 验证码字体,不设置随机获取
     30         'bg'        => array(243, 251, 254),  // 背景颜色
     31         'codeSet'   => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY', /* 验证码中使用的字符,0--o,O 1--l,I, 9--g S--Z容易混淆,建议不用    */
     32         );
     33 
     34     private $_image   = NULL;     // 验证码图片实例
     35     private $_color   = NULL;     // 验证码字体颜色
     36 
     37     // 架构方法 设置参数
     38     public function __construct($config=array()){
     39         $this->config   =   array_merge($this->config, $config);
     40     }
     41 
     42     /**
     43      * 使用 $this->name 获取配置
     44      * @param  string $name 配置名称
     45      * @return multitype    配置值
     46      */
     47     public function __get($name) {
     48         return $this->config[$name];
     49     }
     50 
     51     public function __set($name,$value){
     52         if(isset($this->config[$name])) {
     53             $this->config[$name]    =   $value;
     54         }
     55     }
     56 
     57     public function __isset($name){
     58         return isset($this->config[$name]);
     59     }
     60 
     61     /**
     62      * 验证验证码是否正确
     63      *
     64      * @param string $code 用户验证码
     65      * @return bool 用户验证码是否正确
     66      */
     67     public function check($code, $id = '') {
     68         $key = $this->authcode($this->seKey);
     69         // 验证码不能为空
     70         $session = session($key);
     71         if(empty($code) || empty($session)) {
     72             return false;
     73         }
     74 
     75         $secode = $id ? $session[$id] : $session;
     76         // session 过期
     77         if(NOW_TIME - $secode['verify_time'] > $this->expire) {
     78             session($key, null);
     79             return false;
     80         }
     81 
     82         if($this->authcode(strtoupper($code)) == $secode['verify_code']) {
     83             session($key, null);
     84             return true;
     85         }
     86 
     87         return false;
     88     }
     89 
     90     /**
     91      * 输出验证码并把验证码的值保存的session中
     92      * 验证码保存到session的格式为: array('code' => '验证码值', 'time' => '验证码创建时间');
     93      */
     94     public function entry($id = '') {
     95         // 图片宽(px)
     96         $this->imageW || $this->imageW = $this->length*$this->fontSize*1.5 + $this->length*$this->fontSize/2; 
     97         // 图片高(px)
     98         $this->imageH || $this->imageH = $this->fontSize * 2.5;
     99         // 建立一幅 $this->imageW x $this->imageH 的图像
    100         $this->_image = imagecreate($this->imageW, $this->imageH); 
    101         // 设置背景      
    102         imagecolorallocate($this->_image, $this->bg[0], $this->bg[1], $this->bg[2]); 
    103 
    104         // 验证码字体随机颜色
    105         $this->_color = imagecolorallocate($this->_image, mt_rand(1,150), mt_rand(1,150), mt_rand(1,150));
    106         // 验证码使用随机字体
    107         $ttfPath = dirname(__FILE__) . '/Verify/' . ($this->useZh ? 'zhttfs' : 'ttfs') . '/';
    108 
    109         if(empty($this->fontttf)){
    110             $dir = dir($ttfPath);
    111             $ttfs = array();        
    112             while (false !== ($file = $dir->read())) {
    113                 if($file[0] != '.' && substr($file, -4) == '.ttf') {
    114                     $ttfs[] = $file;
    115                 }
    116             }
    117             $dir->close();
    118             $this->fontttf = $ttfs[array_rand($ttfs)];
    119         } 
    120         $this->fontttf = $ttfPath . $this->fontttf;
    121         
    122         if($this->useImgBg) {
    123             $this->_background();
    124         }
    125         
    126         if ($this->useNoise) {
    127             // 绘杂点
    128             $this->_writeNoise();
    129         } 
    130         if ($this->useCurve) {
    131             // 绘干扰线
    132             $this->_writeCurve();
    133         }
    134         
    135         // 绘验证码
    136         $code = array(); // 验证码
    137         $codeNX = 0; // 验证码第N个字符的左边距
    138         for ($i = 0; $i<$this->length; $i++) {
    139             if($this->useZh) {
    140                 $code[$i] = chr(mt_rand(0xB0,0xF7)).chr(mt_rand(0xA1,0xFE));
    141             } else {
    142                 $codeSetLen = strlen($this->config['codeSet']);
    143                 $code[$i] = $this->config['codeSet'][mt_rand(0,  $codeSetLen - 1)]; //修改,将之前的$this->_codeSet改成 $this->config['codeSet'],将[mt_rand(0, 51)]改成[mt_rand(0,  $codeSetLen - 1)]
    144                 $codeNX += mt_rand($this->fontSize*1.2, $this->fontSize*1.6);
    145                 // 写一个验证码字符
    146                 $this->useZh || imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40), $codeNX, $this->fontSize*1.6, $this->_color, $this->fontttf, $code[$i]);
    147             }
    148         }
    149         
    150         $this->useZh && imagettftext($this->_image, $this->fontSize, 0, ($this->imageW - $this->fontSize*$this->length*1.2)/3, $this->fontSize * 1.5, $this->_color, $this->fontttf, iconv("GB2312","UTF-8", join('', $code)));
    151         
    152         // 保存验证码
    153         $key = $this->authcode($this->seKey);
    154         $code = $this->authcode(strtoupper(implode('', $code)));
    155         $session = array();
    156         if($id) {
    157             $session[$id]['verify_code'] = $code; // 把校验码保存到session
    158             $session[$id]['verify_time'] = NOW_TIME;  // 验证码创建时间
    159         } else {
    160             $session['verify_code'] = $code; // 把校验码保存到session
    161             $session['verify_time'] = NOW_TIME;  // 验证码创建时间
    162         }
    163         session($key, $session);
    164 
    165                 
    166         header('Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate');
    167         header('Cache-Control: post-check=0, pre-check=0', false);        
    168         header('Pragma: no-cache');
    169         header("content-type: image/png");
    170 
    171         // 输出图像
    172         imagepng($this->_image);
    173         imagedestroy($this->_image);
    174     }
    175 
    176     /** 
    177      * 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数) 
    178      *      
    179      *      高中的数学公式咋都忘了涅,写出来
    180      *        正弦型函数解析式:y=Asin(ωx+φ)+b
    181      *      各常数值对函数图像的影响:
    182      *        A:决定峰值(即纵向拉伸压缩的倍数)
    183      *        b:表示波形在Y轴的位置关系或纵向移动距离(上加下减)
    184      *        φ:决定波形与X轴位置关系或横向移动距离(左加右减)
    185      *        ω:决定周期(最小正周期T=2π/∣ω∣)
    186      *
    187      */
    188     private function _writeCurve() {
    189         $px = $py = 0;
    190         
    191         // 曲线前部分
    192         $A = mt_rand(1, $this->imageH/2);                  // 振幅
    193         $b = mt_rand(-$this->imageH/4, $this->imageH/4);   // Y轴方向偏移量
    194         $f = mt_rand(-$this->imageH/4, $this->imageH/4);   // X轴方向偏移量
    195         $T = mt_rand($this->imageH, $this->imageW*2);  // 周期
    196         $w = (2* M_PI)/$T;
    197                         
    198         $px1 = 0;  // 曲线横坐标起始位置
    199         $px2 = mt_rand($this->imageW/2, $this->imageW * 0.8);  // 曲线横坐标结束位置
    200 
    201         for ($px=$px1; $px<=$px2; $px = $px + 1) {
    202             if ($w!=0) {
    203                 $py = $A * sin($w*$px + $f)+ $b + $this->imageH/2;  // y = Asin(ωx+φ) + b
    204                 $i = (int) ($this->fontSize/5);
    205                 while ($i > 0) {    
    206                     imagesetpixel($this->_image, $px + $i , $py + $i, $this->_color);  // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多                
    207                     $i--;
    208                 }
    209             }
    210         }
    211         
    212         // 曲线后部分
    213         $A = mt_rand(1, $this->imageH/2);                  // 振幅        
    214         $f = mt_rand(-$this->imageH/4, $this->imageH/4);   // X轴方向偏移量
    215         $T = mt_rand($this->imageH, $this->imageW*2);  // 周期
    216         $w = (2* M_PI)/$T;        
    217         $b = $py - $A * sin($w*$px + $f) - $this->imageH/2;
    218         $px1 = $px2;
    219         $px2 = $this->imageW;
    220 
    221         for ($px=$px1; $px<=$px2; $px=$px+ 1) {
    222             if ($w!=0) {
    223                 $py = $A * sin($w*$px + $f)+ $b + $this->imageH/2;  // y = Asin(ωx+φ) + b
    224                 $i = (int) ($this->fontSize/5);
    225                 while ($i > 0) {            
    226                     imagesetpixel($this->_image, $px + $i, $py + $i, $this->_color);    
    227                     $i--;
    228                 }
    229             }
    230         }
    231     }
    232 
    233     /**
    234      * 画杂点
    235      * 往图片上写不同颜色的字母或数字
    236      */
    237     private function _writeNoise() {
    238         for($i = 0; $i < 10; $i++){
    239             //杂点颜色
    240             $noiseColor = imagecolorallocate($this->_image, mt_rand(150,225), mt_rand(150,225), mt_rand(150,225));
    241             for($j = 0; $j < 5; $j++) {
    242                 // 绘杂点
    243                 $tmpCodeSet = '2345678abcdefhijkmnpqrstuvwxyz';  //修改,新增了临时变量,用于生成绘杂点
    244                 imagestring($this->_image, 5, mt_rand(-10, $this->imageW),  mt_rand(-10, $this->imageH), $tmpCodeSet[mt_rand(0, strlen($tmpCodeSet)-1)], $noiseColor);
    245             }
    246         }
    247     }
    248 
    249     /**
    250      * 绘制背景图片
    251      * 注:如果验证码输出图片比较大,将占用比较多的系统资源
    252      */
    253     private function _background() {
    254         $path = dirname(__FILE__).'/Verify/bgs/';
    255         $dir = dir($path);
    256 
    257         $bgs = array();        
    258         while (false !== ($file = $dir->read())) {
    259             if($file[0] != '.' && substr($file, -4) == '.jpg') {
    260                 $bgs[] = $path . $file;
    261             }
    262         }
    263         $dir->close();
    264 
    265         $gb = $bgs[array_rand($bgs)];
    266 
    267         list($width, $height) = @getimagesize($gb);
    268         // Resample
    269         $bgImage = @imagecreatefromjpeg($gb);
    270         @imagecopyresampled($this->_image, $bgImage, 0, 0, 0, 0, $this->imageW, $this->imageH, $width, $height);
    271         @imagedestroy($bgImage);
    272     }
    273 
    274     /* 加密验证码 */
    275     private function authcode($str){
    276         $key = substr(md5($this->seKey), 5, 8);
    277         $str = substr(md5($str), 8, 10);
    278         return md5($key . $str);
    279     }
    280 
    281 }
  • 相关阅读:
    【问题:SSH】win10使用SSH链接服务器时,提示:Host key verification failed
    【深度学习大讲堂】首期第三讲:深度学习基础 第一部分:基础结构单元
    【深度学习大讲堂】首期第二讲:深度学习简史
    【深度学习大讲堂】首期第一讲:人工智能的ABCDE 第二部分:简谈当前AI技术与发展趋势
    【深度学习大讲堂】首期第一讲:人工智能的ABCDE 第一部分:从人工智能和计算机视觉说起
    实验吧-隐写-so beautiful so white WP
    实验吧-隐写 最低位的亲吻 WP
    jarvis OJ basic (一) WP
    实验吧web-登入一下好吗
    实验吧web-oncemore
  • 原文地址:https://www.cnblogs.com/BTMaster/p/3547878.html
Copyright © 2011-2022 走看看