zoukankan      html  css  js  c++  java
  • php click captcha 验证码类

    需求:

    现在常用的表单验证码大部分都是要用户输入为主,但这样对手机用户会不方便。

    如果手机用户访问,可以不用输入,而是click某一位置便可确认验证码,这样就会方便很多。


    原理:

    1.使用PHP imagecreate创建PNG图象,在图中画N个圆弧,其中一个是完整的圆(验证用),将圆心坐标及半径记录入session。

    2.在浏览器,当用户在验证码图片上点击时,记录点击的位置。

    3.将用户点击的坐标与session记录的圆心坐标、半径比较,判断是否在圆中,如是则验证通过。



    ClickCaptcha.class.php

    <?php
    /** Click Captcha 验证码类
    *   Date:   2013-05-04
    *   Author: fdipzone
    *   Ver:    1.0
    */
    
    class ClickCaptcha { // class start
    
        public $sess_name = 'm_captcha';
        public $width = 500;
        public $height = 200;
        public $icon = 5;
        public $iconColor = array(255, 255, 0);
        public $backgroundColor = array(0, 0, 0);
        public $iconSize = 56;
    
        private $_img_res = null;
    
    
        public function __construct($sess_name=''){
            if(session_id() == ''){
                session_start();
            }
    
            if($sess_name!=''){
                $this->sess_name = $sess_name; // 设置session name
            }
        }
    
    
        /** 创建验证码 */
        public function create(){
    
            // 创建图象
            $this->_img_res = imagecreate($this->width, $this->height);
            
            // 填充背景
            ImageColorAllocate($this->_img_res, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2]);
    
            // 分配颜色
            $col_ellipse = imagecolorallocate($this->_img_res, $this->iconColor[0], $this->iconColor[1], $this->iconColor[2]);
    
            $minArea = $this->iconSize/2+3;
    
            // 混淆用图象,不完整的圆
            for($i=0; $i<$this->icon; $i++){
                $x = mt_rand($minArea, $this->width-$minArea);
                $y = mt_rand($minArea, $this->height-$minArea);
                $s = mt_rand(0, 360);
                $e = $s + 330;
                imagearc($this->_img_res, $x, $y, $this->iconSize, $this->iconSize, $s, $e, $col_ellipse);            
            }
    
            // 验证用图象,完整的圆
            $x = mt_rand($minArea, $this->width-$minArea);
            $y = mt_rand($minArea, $this->height-$minArea);
            $r = $this->iconSize/2;
            imagearc($this->_img_res, $x, $y, $this->iconSize, $this->iconSize, 0, 360, $col_ellipse);        
    
            // 记录圆心坐标及半径
            $this->captcha_session($this->sess_name, array($x, $y, $r));
    
            // 生成图象
            Header("Content-type: image/PNG");
            ImagePNG($this->_img_res);
            ImageDestroy($this->_img_res);
    
            exit();
        }
    
    
        /** 检查验证码
        * @param String $captcha  验证码
        * @param int    $flag     验证成功后 0:不清除session 1:清除session
        * @return boolean
        */
        public function check($captcha, $flag=1){
            if(trim($captcha)==''){
                return false;
            }
            
            if(!is_array($this->captcha_session($this->sess_name))){
                return false;
            }
    
            list($px, $py) = explode(',', $captcha);
            list($cx, $cy, $cr) = $this->captcha_session($this->sess_name);
    
            if(isset($px) && is_numeric($px) && isset($py) && is_numeric($py) && 
                isset($cx) && is_numeric($cx) && isset($cy) && is_numeric($cy) && isset($cr) && is_numeric($cr)){
                if($this->pointInArea($px,$py,$cx,$cy,$cr)){
                    if($flag==1){
                        $this->captcha_session($this->sess_name,'');
                    }
                    return true;
                }
            }
            return false;
        }
    
    
        /** 判断点是否在圆中
        * @param int $px  点x
        * @param int $py  点y
        * @param int $cx  圆心x
        * @param int $cy  圆心y
        * @param int $cr  圆半径
        * sqrt(x^2+y^2)<r
        */
        private function pointInArea($px, $py, $cx, $cy, $cr){
            $x = $cx-$px;
            $y = $cy-$py;
            return round(sqrt($x*$x + $y*$y))<$cr;
        }
    
    
        /** 验证码session处理方法
        * @param   String   $name    captcha session name
        * @param   String   $value
        * @return  String
        */
        private function captcha_session($name,$value=null){
            if(isset($value)){
                if($value!==''){
                    $_SESSION[$name] = $value;
                }else{
                    unset($_SESSION[$name]);
                }
            }else{
                return isset($_SESSION[$name])? $_SESSION[$name] : '';
            }
        }
    
    } // class end
    
    ?>

    demo.php
    <?php
    session_start();
    require('ClickCaptcha.class.php');
    
    if(isset($_GET['get_captcha'])){ // get captcha
        $obj = new ClickCaptcha();
        $obj->create();
        exit();
    }
    
    if(isset($_POST['send']) && $_POST['send']=='true'){ // submit
        $name = isset($_POST['name'])? trim($_POST['name']) : '';
        $captcha = isset($_POST['captcha'])? trim($_POST['captcha']) : '';
    
        $obj = new ClickCaptcha();
    
        if($obj->check($captcha)){
            echo 'your name is:'.$name;
        }else{
            echo 'captcha not match';
        }
        echo ' <a href="demo.php">back</a>';
    
    }else{ // html
    ?>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
     <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <title> Click Captcha Demo </title>
      <script type="text/javascript" src="jquery-1.6.2.min.js"></script>
      <script type="text/javascript">
        $(function(){
            $('#captcha_img').click(function(e){
                var x = e.pageX - $(this).offset().left;
                var y = e.pageY - $(this).offset().top;
                $('#captcha').val(x+','+y);
            })
    
            $('#btn').click(function(e){
                if($.trim($('#name').val())==''){
                    alert('Please input name!');
                    return false;
                }
    
                if($.trim($('#captcha').val())==''){
                    alert('Please click captcha!');
                    return false;
                }
                $('#form1')[0].submit();
            })
        })
      </script>
     </head>
    
     <body>
        <form name="form1" id="form1" method="post" action="demo.php" onsubmit="return false">
        <p>name:<input type="text" name="name" id="name"></p>
        <p>Captcha:Please click full circle<br><img id="captcha_img" src="demo.php?get_captcha=1&t=<?=time() ?>" style="cursor:pointer"></p>
        <p><input type="submit" id="btn" value="submit"></p>
        <input type="hidden" name="send" value="true">
        <input type="hidden" name="captcha" id="captcha">
        </form>
     </body>
    </html>
    <?php } ?>

    源码下载:点击下载

  • 相关阅读:
    CGI编程完全手册(转)
    Linux下读写芯片的I2C寄存器(转)
    Linux内核中_IO,_IOR,_IOW,_IOWR宏的用法与解析
    H264中的SPS、PPS提取与作用(转)
    H264码流打包分析(精华)--转
    嵌入式Linux USB WIFI驱动的移植(转)
    推荐一款技术人必备的接口测试神器:Apifox
    Java 设置、删除、获取Word文档背景(基于Spire.Cloud.SDK for Java)
    Java 添加、删除、格式化Word中的图片( 基于Spire.Cloud.SDK for Java )
    Java 添加、删除、替换、格式化Word中的文本(基于Spire.Cloud.SDK for Java)
  • 原文地址:https://www.cnblogs.com/fdipzone/p/3715122.html
Copyright © 2011-2022 走看看