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 相关文章推荐
一个从别的网站抓取信息的例子(域名查询)
Oct 09 PHP
PHP实现定时生成HTML网站首页实例代码
Nov 20 PHP
一个php导出oracle库的php代码
Apr 20 PHP
使用gd库实现php服务端图片裁剪和生成缩略图功能分享
Dec 25 PHP
PHP判断网络文件是否存在的方法
Mar 12 PHP
Symfony2开发之控制器用法实例分析
Feb 05 PHP
又拍云异步上传实例教程详解
Apr 19 PHP
CI框架支持$_GET的两种实现方法
May 18 PHP
PHP中的函数声明与使用详解
May 27 PHP
thinkphp5 URL和路由的功能详解与实例
Dec 26 PHP
Laravel5.4框架使用socialite实现github登录的方法
Mar 20 PHP
php常用字符串长度函数strlen()与mb_strlen()用法实例分析
Jun 25 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 array_unique之后json_encode需要注意
2011/01/02 PHP
php基于闭包实现函数的自调用(递归)实例分析
2016/11/11 PHP
PHP实现将多个文件压缩成zip格式并下载到本地的方法示例
2018/05/23 PHP
WordPress 插件——CoolCode使用方法与下载
2007/07/02 Javascript
jQuery的链式调用浅析
2010/12/03 Javascript
jQuery渐变发光导航菜单的实例代码
2013/03/27 Javascript
js对table的td进行相同内容合并示例详解
2013/12/27 Javascript
jquery获取radio值(单选组radio)
2014/10/16 Javascript
js replace(a,b)之替换字符串中所有指定字符的方法
2016/08/17 Javascript
docker中编译nodejs并使用nginx启动
2017/06/23 NodeJs
jQuery Layer弹出层传值到父页面的实现代码
2017/08/17 jQuery
Vue 拦截器对token过期处理方法
2018/01/23 Javascript
node前端开发模板引擎Jade的入门
2018/05/11 Javascript
关于vue的语法规则检测报错问题的解决
2018/05/21 Javascript
使用vue-router完成简单导航功能【推荐】
2018/06/28 Javascript
node事件循环和process模块实例分析
2020/02/14 Javascript
Vue通过getAction的finally来最大程度避免影响主数据呈现问题
2020/04/24 Javascript
node中短信api实现验证码登录的示例代码
2021/01/20 Javascript
[08:06]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant 选手采访
2021/03/11 DOTA
Python 调用VC++的动态链接库(DLL)
2008/09/06 Python
浅谈插入排序算法在Python程序中的实现及简单改进
2016/05/04 Python
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
python 字符串和整数的转换方法
2018/06/25 Python
python调用java的jar包方法
2018/12/15 Python
python flask解析json数据不完整的解决方法
2019/05/26 Python
使用Python画股票的K线图的方法步骤
2019/06/28 Python
vue常用指令代码实例总结
2020/03/16 Python
基于pandas向csv添加新的行和列
2020/05/25 Python
python对 MySQL 数据库进行增删改查的脚本
2020/10/22 Python
python中scipy.stats产生随机数实例讲解
2021/02/19 Python
Zavvi美国:英国娱乐之家
2017/03/19 全球购物
薇诺娜官方网上商城:专注敏感肌肤
2017/05/25 全球购物
四风存在的原因分析
2014/02/11 职场文书
python引入其他文件夹下的py文件具体方法
2021/05/23 Python
Redisson实现Redis分布式锁的几种方式
2021/08/07 Redis
MySQL外键约束(FOREIGN KEY)案例讲解
2021/08/23 MySQL