PHP实现GIF图片验证码


Posted in PHP onNovember 04, 2015

这是一个用PHP生成GIF动画来实现动态图片验证码的程序,非常实用,是php用户注册登录界面经常需要用到的验证码程序,有需要GIF动态图片验证码功能的朋友可以收藏一下。
第一步:创建ImageCode.php文件,验证码生成函数代码如下:

<?php
/**
 * ImageCode 生成GIF图片验证
 * @param $string 字符串
 * @param $width 宽度
 * @param $height 高度
 * */
function ImageCode($string = '', $width = 75, $height = 25)
{
  $authstr = $string ? $string : ((time() % 2 == 0) ? mt_rand(1000, 9999) : mt_rand(10000, 99999));
  $board_width = $width;
  $board_height = $height;
  // 生成一个32帧的GIF动画
  for($i = 0; $i < 32; $i++)
  {
    ob_start();
    $image = imagecreate($board_width, $board_height);
    imagecolorallocate($image, 0,0,0);
    // 设定文字颜色数组
    $colorList[] = ImageColorAllocate($image, 15,73,210);
    $colorList[] = ImageColorAllocate($image, 0,64,0);
    $colorList[] = ImageColorAllocate($image, 0,0,64);
    $colorList[] = ImageColorAllocate($image, 0,128,128);
    $colorList[] = ImageColorAllocate($image, 27,52,47);
    $colorList[] = ImageColorAllocate($image, 51,0,102);
    $colorList[] = ImageColorAllocate($image, 0,0,145);
    $colorList[] = ImageColorAllocate($image, 0,0,113);
    $colorList[] = ImageColorAllocate($image, 0,51,51);
    $colorList[] = ImageColorAllocate($image, 158,180,35);
    $colorList[] = ImageColorAllocate($image, 59,59,59);
    $colorList[] = ImageColorAllocate($image, 0,0,0);
    $colorList[] = ImageColorAllocate($image, 1,128,180);
    $colorList[] = ImageColorAllocate($image, 0,153,51);
    $colorList[] = ImageColorAllocate($image, 60,131,1);
    $colorList[] = ImageColorAllocate($image, 0,0,0);
    $fontcolor = ImageColorAllocate($image, 0,0,0);
    $gray = ImageColorAllocate($image, 245,245,245);    
    $color = imagecolorallocate($image, 255,255,255);
    $color2 = imagecolorallocate($image, 255,0,0);
    imagefill($image, 0, 0, $gray);
    $space = 15;    // 字符间距
    if($i > 0)      // 屏蔽第一帧
    {
      for ($k = 0; $k < strlen($authstr); $k++)
      {
        $colorRandom = mt_rand(0,sizeof($colorList)-1);
        $float_top = rand(0,4);
        $float_left = rand(0,3);
        imagestring($image, 6, $space * $k, $top + $float_top, substr($authstr, $k, 1), $colorList[$colorRandom]);
      }
    }

    for ($k = 0; $k < 20; $k++)
    {
      $colorRandom = mt_rand(0,sizeof($colorList)-1);
      imagesetpixel($image, rand()%70 , rand()%15 , $colorList[$colorRandom]);  
    }
    // 添加干扰线
    for($k = 0; $k < 3; $k++)
    {
      $colorRandom = mt_rand(0, sizeof($colorList)-1);
      // $todrawline = rand(0,1);
      $todrawline = 1;
      if($todrawline)
      {
        imageline($image, mt_rand(0, $board_width), mt_rand(0,$board_height), mt_rand(0,$board_width), mt_rand(0,$board_height), $colorList[$colorRandom]);
      }
      else
      {
        $w = mt_rand(0,$board_width);
        $h = mt_rand(0,$board_width);
        imagearc($image, $board_width - floor($w / 2) , floor($h / 2), $w, $h, rand(90,180), rand(180,270), $colorList[$colorRandom]);
      }
    }
    imagegif($image);
    imagedestroy($image);
    $imagedata[] = ob_get_contents();
    ob_clean(); 
    ++$i; 
  }  
  $gif = new GIFEncoder($imagedata); 
  Header ('Content-type:image/gif'); 
  echo $gif->GetAnimation(); 
}
/**
 * GIFEncoder类
 * */
Class GIFEncoder
{
  var $GIF = "GIF89a";        /* GIF header 6 bytes    */ 
  var $VER = "GIFEncoder V2.06";    /* Encoder version       */ 
  var $BUF = Array ( ); 
  var $LOP = 0; 
  var $DIS = 2; 
  var $COL = -1; 
  var $IMG = -1; 
  var $ERR = Array ( 
    'ERR00' =>"Does not supported function for only one image!", 
    'ERR01' =>"Source is not a GIF image!", 
    'ERR02' =>"Unintelligible flag ", 
    'ERR03' =>"Could not make animation from animated GIF source", 
  ); 
  function GIFEncoder ($GIF_src, $GIF_dly = 100, $GIF_lop = 0, $GIF_dis = 0, $GIF_red = 0, $GIF_grn = 0, $GIF_blu = 0, $GIF_mod = 'bin' )
  { 
    if (!is_array($GIF_src) && !is_array($GIF_tim))
    { 
      printf ( "%s: %s", $this->VER, $this->ERR['ERR00']); 
      exit( 0 );
    } 
    $this->LOP = ($GIF_lop > -1) ? $GIF_lop : 0;
    $this->DIS = ($GIF_dis > -1) ? (( $GIF_dis < 3 ) ? $GIF_dis : 3) : 2; 

    $this->COL = ($GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1) ? ($GIF_red | ($GIF_grn << 8) | ($GIF_blu << 16)) : -1; 
    for ($i = 0, $src_count = count($GIF_src); $i < $src_count; $i++ )

    {
      if (strToLower( $GIF_mod ) == "url")
      { 
        $this->BUF[] = fread (fopen($GIF_src [$i], "rb"), filesize ($GIF_src [$i])); 
      } 
      elseif(strToLower($GIF_mod) == "bin")
      { 

        $this->BUF [ ] = $GIF_src [ $i ]; 
      } 
      else
      { 
        printf("%s: %s ( %s )!", $this->VER, $this->ERR [ 'ERR02' ], $GIF_mod); 

        exit(0); 
      } 
      if (substr($this->BUF[$i], 0, 6) != "GIF87a" && substr($this->BUF [$i], 0, 6) != "GIF89a")

      { 

        printf( "%s: %d %s", $this->VER, $i, $this->ERR ['ERR01']); 

        exit(0); 
      } 
      for ($j = (13 + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07 ))), $k = TRUE; $k; $j++)
      { 
        switch ($this->BUF [$i]{$j})
        { 
          case "!": 
            if ((substr($this->BUF[$i], ($j + 3), 8)) == "NETSCAPE")
            { 
                printf( "%s: %s ( %s source )!", $this->VER, $this->ERR ['ERR03'], ($i + 1)); 
                exit( 0 ); 
            } 
            break; 
            case ";": 
            $k = FALSE; 
            break; 
        } 
      } 
    } 
    GIFEncoder::GIFAddHeader(); 
    for($i = 0, $count_buf = count($this->BUF); $i < $count_buf; $i++)
    { 
      GIFEncoder::GIFAddFrames($i, $GIF_dly[$i]); 
    } 
    GIFEncoder::GIFAddFooter(); 
  } 
  function GIFAddHeader ( )
  { 
    $cmap = 0; 
    if (ord($this->BUF[0]{10}) & 0x80 )
    { 
      $cmap = 3 * ( 2 << ( ord ( $this->BUF [ 0 ]{10} ) & 0x07 )); 
       
      $this->GIF .= substr ( $this->BUF [ 0 ], 6, 7); 

      $this->GIF .= substr ( $this->BUF [ 0 ], 13, $cmap); 
      $this->GIF .= "!\377\13NETSCAPE2.0\3\1" . GIFEncoder::GIFWord ( $this->LOP ) . "\0"; 
    } 
  } 
  function GIFAddFrames ( $i, $d )
  { 
    $Locals_str = 13 + 3 * (2 <<(ord($this->BUF[$i]{10}) & 0x07)); 
    $Locals_end = strlen($this->BUF[$i]) - $Locals_str - 1; 
    $Locals_tmp = substr ($this->BUF[$i], $Locals_str, $Locals_end); 
    $Global_len = 2 << (ord( $this->BUF [0]{10} ) & 0x07 ); 
    $Locals_len = 2 << (ord( $this->BUF[$i]{10}) & 0x07); 
    $Global_rgb = substr($this->BUF[0], 13, 3 * (2 << ( ord ( $this->BUF[0]{10} ) & 0x07))); 
    $Locals_rgb = substr ( $this->BUF[$i], 13, 3 * (2 << ( ord ( $this->BUF[$i]{10} ) & 0x07))); 
    $Locals_ext = "!\xF9\x04" . chr(($this->DIS << 2) + 0) . chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . "\x0\x0"; 
    if ( $this->COL > -1 && ord($this->BUF[$i]{10}) & 0x80)

    { 
      for($j = 0; $j < (2 << (ord( $this->BUF[$i]{10}) & 0x07)); $j++ )
      { 
        if(ord ($Locals_rgb{3 * $j + 0}) == ($this->COL >> 0) & 0xFF && ord ( $Locals_rgb { 3 * $j + 1 } ) == ( $this->COL >> 8 ) & 0xFF && ord ( $Locals_rgb { 3 * $j + 2 } ) == ( $this->COL >> 16 ) & 0xFF )

        { 
          $Locals_ext = "!\xF9\x04" . chr(($this->DIS << 2) + 1) . chr (( $d >> 0) & 0xFF) . chr (( $d >> 8) & 0xFF) . chr ($j) . "\x0"; 
          break; 
        } 
      } 

    } 
    switch ( $Locals_tmp { 0 } )

    { 
      case "!": 
        $Locals_img = substr($Locals_tmp, 8, 10); 
        $Locals_tmp = substr($Locals_tmp, 18, strlen ($Locals_tmp) - 18); 
        break; 
      case ",": 
        $Locals_img = substr($Locals_tmp, 0, 10); 
        $Locals_tmp = substr($Locals_tmp, 10, strlen($Locals_tmp) - 10); 
        break; 
    } 
    if ( ord ( $this->BUF[$i]{10} ) & 0x80 && $this->IMG > -1 )
    { 
      if ( $Global_len == $Locals_len )
      { 
        if ( GIFEncoder::GIFBlockCompare ( $Global_rgb, $Locals_rgb, $Global_len ) )
        { 
          $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp ); 
        } 
        else
        { 
          $byte = ord ( $Locals_img{9}); 
          $byte |= 0x80; 
          $byte &= 0xF8; 
          $byte |= ( ord ( $this->BUF [ 0 ]{10}) & 0x07); 

          $Locals_img{9} = chr($byte); 

          $this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp); 
        } 
      } 
      else

      { 
        $byte = ord($Locals_img{9}); 
        $byte |= 0x80; 
        $byte &= 0xF8; 
        $byte |= (ord($this->BUF[$i]{10}) & 0x07); 
        $Locals_img {9} = chr($byte); 
        $this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp); 
      } 
    } 
    else
    { 
      $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp ); 
    } 
    $this->IMG = 1; 

  } 
  function GIFAddFooter ( ) { 
    $this->GIF .= ";"; 
  } 
  function GIFBlockCompare ( $GlobalBlock, $LocalBlock, $Len )
  { 
    for ( $i = 0; $i < $Len; $i++ )

    { 

      if($GlobalBlock { 3 * $i + 0 } != $LocalBlock { 3 * $i + 0 } || $GlobalBlock { 3 * $i + 1 } != $LocalBlock { 3 * $i + 1 } || $GlobalBlock { 3 * $i + 2 } != $LocalBlock{3 * $i + 2})
      { 
        return ( 0 ); 
      } 
    } 

    return ( 1 ); 
  } 
  function GIFWord ( $int )
  { 
    return ( chr ( $int & 0xFF ) . chr ( ( $int >> 8 ) & 0xFF ) ); 
  } 
   
  function GetAnimation ( )
  { 
    return ($this->GIF); 
  } 
}

第二步:验证码生成,创建yzimg.php,并引用入文件ImageCode.php。代码如下:

<?php
if(!isset($_SESSION)){
  session_start();
}
require_once(dirname(__FILE__)."ImageCode.php");
unset($_SESSION['yzm']);
$randCode = '';
$chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPRSTUVWXYZ23456789';
for ( $i = 0; $i < 4; $i++ )
{
  $randCode .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
$_SESSION['yzm']=$randCode;     // 记录session
ImageCode($randCode, 60);
 
/*方法二*/
/*$authstr = mt_rand(1000, 9999);  // 生成随机字符串
$_SESSION['yzm'] = $authstr;  // 记录session
ImageCode($authstr, 60);  // 显示GIF动画*/
?>

 第三步:调用和显示验证码,在需要添加验证码的页面加入以下代码,代码如下:

<input name="yzm" type="text" class="input1" size="12" style="width:70px;"/>
         <SCRIPT LANGUAGE="JavaScript">
<!--
document.write('<img id="yz_Img" name="imageField" class="yz_Img" title="刷新验证码" onclick="this.src=this.src+Math.random();" src="yzimg.php?'+Math.random()+'">');
//-->
</SCRIPT>

以上就是为大家分享的如何使用php生成动态验证码的相应代码,希望对大家的学习有所帮助。

PHP 相关文章推荐
js下函数般调用正则的方法附代码
Jun 22 PHP
thinkphp实现发送邮件密码找回功能实例
Dec 01 PHP
PHP查询并删除数据库多列重复数据的方法(利用数组函数实现)
Feb 23 PHP
PHP获取页面执行时间的方法(推荐)
Dec 10 PHP
PHP进制转换实例分析(2,8,16,36,64进制至10进制相互转换)
Feb 04 PHP
php+mysql+ajax实现单表多字段多关键词查询的方法
Apr 15 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
Jan 29 PHP
PHP调用接口用post方法传送json数据的实例
May 31 PHP
php使用curl获取header检测开启GZip压缩的方法
Aug 15 PHP
PHP精确到毫秒秒杀倒计时实例详解
Mar 14 PHP
tp5.1 实现setInc字段自动加1
Oct 18 PHP
laravel7学习之无限级分类的最新实现方法
Sep 30 PHP
php实现分页显示
Nov 03 #PHP
PHP翻页跳转功能实现方法
Nov 30 #PHP
php中注册器模式类用法实例分析
Nov 03 #PHP
php实现zip文件解压操作
Nov 03 #PHP
thinkphp如何获取客户端IP
Nov 03 #PHP
php去除二维数组的重复项方法
Nov 03 #PHP
php在数据库抽象层简单使用PDO的方法
Nov 03 #PHP
You might like
新版PHP将向Java靠拢
2006/10/09 PHP
mayfish 数据入库验证代码
2010/04/30 PHP
php中使用preg_match_all匹配文章中的图片
2013/02/06 PHP
ThinkPHP3.1数据CURD操作快速入门
2014/06/19 PHP
LNMP部署laravel以及xhprof安装使用教程
2017/09/14 PHP
基于JQuery的模拟苹果桌面Dock效果(稳定版)
2012/10/15 Javascript
基于JQuery实现的图片自动进行缩放和裁剪处理
2014/01/31 Javascript
提升PHP安全:8个必须修改的PHP默认配置
2014/11/17 Javascript
浅谈javascript中的instanceof和typeof
2015/02/27 Javascript
javascript关于运动的各种问题经典总结
2015/04/27 Javascript
JavaScript电子时钟倒计时
2016/01/09 Javascript
简单了解Backbone.js的Model模型以及View视图的源码
2016/02/14 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
2019/09/06 Javascript
vue实现在进行增删改操作后刷新页面
2020/08/05 Javascript
python通过ElementTree操作XML获取结点读取属性美化XML
2013/12/02 Python
Eclipse中Python开发环境搭建简单教程
2016/03/23 Python
Python正则表达式完全指南
2017/05/25 Python
python自定义异常实例详解
2017/07/11 Python
Python实现读取邮箱中的邮件功能示例【含文本及附件】
2017/08/05 Python
python 设置文件编码格式的实现方法
2017/12/21 Python
Python爬虫实例扒取2345天气预报
2018/03/04 Python
基于Django快速集成Echarts代码示例
2020/12/01 Python
IE8下CSS3选择器nth-child() 不兼容问题的解决方法
2016/11/16 HTML / CSS
英国领先的新鲜松露和最好的松露产品供应商:TruffleHunter
2019/08/26 全球购物
英文版销售经理个人求职信
2013/11/20 职场文书
心碎乌托邦的创业计划书范文
2013/12/26 职场文书
廉洁使者实施方案
2014/03/29 职场文书
图书馆志愿者活动总结
2014/06/27 职场文书
三八活动策划方案
2014/08/17 职场文书
2014年最新领导班子整改方案
2014/09/27 职场文书
初二学生评语大全
2014/12/26 职场文书
小浪底导游词
2015/02/12 职场文书
旅游项目合作意向书
2015/05/08 职场文书
答谢酒会主持词
2015/07/02 职场文书
初中毕业生感言
2015/07/31 职场文书
golang slice元素去重操作
2021/04/30 Golang