php 验证码(倾斜,正弦干扰线,黏贴,旋转)

好久没有写帖子了。一直忙着新的项目。 最近,做验证码程序,一直想做一个简洁大方,自动识别比较困难的。 通过这些时候整理搜集,发现一般做法有以下几种方案:
1、字体变型 (一般通过算法,进行扭曲,比较有代表性就是:http://code.google.com/p/cool-php-captcha/

2、字体黏贴 (这里面以qq验证码为代表了,目前网上还是很难找到,破解qq验证码的)

3、干扰线,噪点 (这种识别起来相当容易,很容易被程序自动化识别)
对于上面提到,第1,2 二种方法,在识别时候,是比较困难的。个人比较喜欢第二种方法,感觉看起来不是很费力。而扭曲的文字,总觉得怪怪的。 哈哈,纯粹个人喜好了。
实现代码:


代码如下:

<?php
/**
 *带文字旋转,倾斜,黏贴,加正弦干扰线验证码*
 *@version  0.1
 *@author http://www.cnblogs.com/chengmo
 *@copyright 程默 QQ:8292669
 */
class Utils_Caption
{
 var $Width      = 60;           //图片宽
 var $Height     = 30;           //图片高
 var $Length     = 4;            //验证码位数
 var $BgColor    = "#FFFFFF";    //背景色
 var $TFonts = array("font.ttf");
 var $TFontSize=array(17,20); //字体大小范围
 var $TFontAngle=array(-20,20); //旋转角度
 var $Chars   = "0123456789";         //验证码范围(字母数字)
 var $Code    = array();              //验证码
 var $Image   = "";              //图形对象
 var $FontColors=array('#f36161','#6bc146','#5368bd');  //字体颜色,红绿蓝
 var $TPadden = 0.75;///字符间距,多少个字符
 var $Txbase = 5;///x轴两边距离
 var $Tybase =5 ;///y轴两边距离
 var $TLine =true; ///画干扰线
 public  function RandRSI() ///生成验证码
 {
  $this->TFontAngle=range($this->TFontAngle[0],$this->TFontAngle[1]);
  $this->TFontSize=range($this->TFontSize[0],$this->TFontSize[1]);
  $arr=array();
  $Chars=$this->Chars;
  $TFontAngle=$this->TFontAngle;
  $TFontSize=$this->TFontSize;
  $FontColors=$this->FontColors;
  $code="";
  $font=dirname(__FILE__)."/font/".$this->TFonts[0];
  $charlen=strlen($Chars)-1;
  $anglelen=count($TFontAngle)-1; // 角度范围
  $fontsizelen=count($TFontSize)-1; // 角度范围
  $fontcolorlen=count($FontColors)-1; // 角度范围
  for($i=0;$i<$this->Length;$i++) ///得到字符与颜色
  {
   $char=$Chars[rand(0,$charlen)]; ///得到字符
   $angle=$TFontAngle[rand(0,$anglelen)]; ///旋转角度
   $fontsize=$TFontSize[rand(0,$fontsizelen)]; ///字体大小
   $fontcolor=$FontColors[rand(0,$fontcolorlen)]; ///字体大小
   $bound=$this->_calculateTextBox($fontsize,$angle,$font,$char); ///得到范围
   $arr[]=array($fontsize,$angle,$fontcolor,$char,$font,$bound);  ///得到矩形框
   $code.=$char;
  }
  $this->Code=$arr; //验证码
  return $code;
 }
 public function Draw() ///画图
 {
  if(empty($this->Code)) $this->RandRSI();
  $codes=$this->Code; ///用户验证码
  $wh=$this->_getImageWH($codes);
  $width=$wh[0];
  $height=$wh[1]; ///高度
  $this->Width=$width;
  $this->Height=$height;
  $this->Image = imageCreate( $width, $height );
  $image=$this->Image;
  $back = $this->_getColor2($this->_getColor( $this->BgColor)); ///背景颜色
  imageFilledRectangle($image, 0, 0, $width, $height, $back); ///填充背景
  $TPadden=$this->TPadden;
  $basex=$this->Txbase;
  $color=null;
  foreach ($codes as $v) ///逐个画字符
  {
   $bound=$v[5];
   $color=$this->_getColor2($this->_getColor($v[2]));
   imagettftext($image, $v[0], $v[1], $basex, $bound['height'],$color , $v[4], $v[3]);
   $basex=$basex+$bound['width']*$TPadden-$bound['left'];///计算下一个左边距
  }
  $this->TLine?$this->_wirteSinLine($color,$basex):null; ///画干扰线
  header("Content-type: image/png");
  imagepng( $image);
  imagedestroy($image);
 }
 /**
  *通过字体角度得到字体矩形宽度*
  *
  * @param int $font_size 字体尺寸
  * @param float $font_angle 旋转角度
  * @param string $font_file 字体文件路径
  * @param string $text 写入字符
  * @return array 返回长宽高
  */
 private function _calculateTextBox($font_size, $font_angle, $font_file, $text) {
  $box = imagettfbbox($font_size, $font_angle, $font_file, $text);
  $min_x = min(array($box[0], $box[2], $box[4], $box[6]));
  $max_x = max(array($box[0], $box[2], $box[4], $box[6]));
  $min_y = min(array($box[1], $box[3], $box[5], $box[7]));
  $max_y = max(array($box[1], $box[3], $box[5], $box[7]));
  return array(
  'left' => ($min_x >= -1) ? -abs($min_x + 1) : abs($min_x + 2),
  'top' => abs($min_y),
  'width' => $max_x - $min_x,
  'height' => $max_y - $min_y,
  'box' => $box
  );
 }
 private function  _getColor( $color ) //#ffffff
 {
  return array(hexdec($color[1].$color[2]),hexdec($color[3].$color[4]),hexdec($color[5].$color[6]));
 }
 private function  _getColor2( $color ) //#ffffff
 {
  return imagecolorallocate ($this->Image, $color[0], $color[1], $color[2]);
 }
 private function _getImageWH($data)
 {
  $TPadden=$this->TPadden;
  $w=$this->Txbase;
  $h=0;
  foreach ($data as $v)
  {
   $w=$w+$v[5]['width']*$TPadden-$v[5]['left'];
   $h=$h>$v[5]['height']?$h:$v[5]['height'];
  }
  return array(max($w,$this->Width),max($h,$this->Height));
 }
 //画正弦干扰线
 private function _wirteSinLine($color,$w)
 {
  $img=$this->Image;
  $h=$this->Height;
  $h1=rand(-5,5);
  $h2=rand(-1,1);
  $w2=rand(10,15);
  $h3=rand(4,6);
  for($i=-$w/2;$i<$w/2;$i=$i+0.1)
  {
   $y=$h/$h3*sin($i/$w2)+$h/2+$h1;
   imagesetpixel($img,$i+$w/2,$y,$color);
   $h2!=0?imagesetpixel($img,$i+$w/2,$y+$h2,$color):null;
  }
 }
}

外带字体:
font.ttf ,一个简单粗体文件。

说明:先看下运行效果吧,大家也不要忙着复制运行了。


主要特点是:旋转,然后黏贴,干扰线是线粗细可以变,然后正弦波形可以变化。
比较复杂是:calculateTextBox 这个函数,这个是得到字符旋转后的宽度高度。
demo:


代码如下:

$rsi = new Utils_Caption();
$rsi->TFontSize=array(15,17);
$rsi->Width=50;
$rsi->Height=25;
$code = $rsi->RandRSI();
session_start();
$_SESSION["CHECKCODE"] = $code;
$rsi->Draw();

好了,就写这么些了,代码还有很多不足之处。
点击下载代码

(0)

相关推荐

  • PHP生成验证码时“图像因其本身有错无法显示”的解决方法

    今天使用代码进行PHP生成校验码功能的实现,发现firefox一直提示"图像.......因其本身有错无法显示"的问题,作者也提示了说"如果浏览器显示"图像XXX因其本身有错无法显示",可尽量去掉文中空格",但把代码中所有空格都去掉了还是不能显示检验图片. 于是深度google,大部分的解决方案也是将"<?"这句代码前的空格回车一切都删掉以防止有html输出,但这根本解决不了我的问题,后来看到有人在Header(&quo

  • PHP实现的封装验证码类详解

    用PHP写一个验证码类,并进行封装.类名: validationcode.class.php代码如下: 复制代码 代码如下: <?php class ValidationCode {  private $width;  private $height;  private $codeNum;  private $image;   //图像资源  private $disturbColorNum;  private $checkCode;  function __construct($width=8

  • 如何用php生成扭曲及旋转的验证码图片

    复制代码 代码如下: <?php function make_rand($length="32"){//验证码文字生成函数         $str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";     $result="";     for($i=0;$i<$length;$i++){         $num[$i]=rand(0,61);   

  • PHP生成Gif图片验证码

    先看效果图  字体及字体文件的路径需要在类中$FontFilePath及$FontFileName中设置.如: 复制代码 代码如下: private static $FontFilePath = "static/font/"; //相对地本代码文件的位置private static $FontFileName = array("3.ttf");// array("1.ttf", "2.ttf", "3.ttf&quo

  • PHP 验证码不显示只有一个小红叉的解决方法

    最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误:  (1)修改步骤如下,原因如下,原因是apache权限没开,  (2)点击打开php.int., 搜索extension=php_gd2.dll 打开?去掉前面分号重启apache,就OK了 ,万事大吉了.  希望各位朋友遇到这样的问题的时候,能给与帮助

  • PHP自定义大小验证码的方法详解

    复制代码 代码如下: <?phpfunction vCode($num=4,$size=20, $width=0,$height=0){         !$width && $width = $num*$size*4/5+5;         !$height && $height = $size + 10;         // 去掉了 0 1 O l 等             $str = "23456789abcdefghijkmnpqrstuvw

  • 一个好用的PHP验证码类实例分享

    分享一个好用的php验证码类,包括调用示例.说明:如果不适用指定的字体,那么就用imagestring()函数,如果需要遇到指定的字体,就要用到imagettftext()函数.字体的位置在C盘下Windows/Fonts. 参考了网上的php 生成验证码的方法,以及php 图片验证码和php 中文验证码的生成方法.用到了PHP GD库的相关知识. 1,生成验证码的类 VerificationCode.class.php 复制代码 代码如下: <?php      class Verificat

  • php中文验证码实现示例分享

    复制代码 代码如下: <?php $text = '的一是不了能好都然没日于起还发成事只作当想看文无开手十用主行方又如前所本见经头面公同三已老从动两长知民样现分将外但身些与高意进把法此实回二理美点月明其种声全工己话儿者向情部正名定女问力机给等几很业最间新什打便位因重被走电四第门相次东政海口使教西再平真听世气信北少关并内加化由却代军产入先山五太水万市眼体别处总才场师书比住员九笑性通目华报立马命张活难神数件安表原车白应路期叫死常提感金何更反合放做系计或司利受光王果亲界及今京务制解各任至清物台象记边共

  • php实现加减法验证码代码

    复制代码 代码如下: <?php/*图片验证码文件,加减计算方式*/ class ImageCode{ private $Jiashu  = 0;        //加数或者减数 private $JianShu = 0;        //被加数或者被减数 private $YunSuan = '';       //运算符 private $DeShu   = 0;        //得数 private $String  = '';       //字符串样式 private $Img; 

  • 一个漂亮的php验证码类(分享)

    直接上代码: 复制代码 代码如下: //验证码类class ValidateCode { private $charset = 'abcdefghkmnprstuvwxyzABCDEFGHKMNPRSTUVWXYZ23456789';//随机因子 private $code;//验证码 private $codelen = 4;//验证码长度 private $width = 130;//宽度 private $height = 50;//高度 private $img;//图形资源句柄 pri

  • 探讨如何在php168_cms中提取验证码

    复制代码 代码如下: <?phpfunction yzImg($nmsg){ if (function_exists('imagecreatetruecolor')){  $imstr[0]["s"]=$nmsg[0];  $imstr[1]["s"]=$nmsg[1];  $imstr[2]["s"]=$nmsg[2];  $imstr[3]["s"]=$nmsg[3];  //文件头...  header("

  • 生成随机字符串和验证码的类的PHP实例

    网上有很多的php随机数与验证码的代码与文章,真正适用的没有几个. 索性自己搞一个吧. 开始本节的php教程 吧,以下代码的实现,主要做到可以很好区分一个get_code(),另一个create_check_image(),输出图像直接调用后面的,session()取验证码时直接get_code()就ok,顺带提下使用session时必须将session_star()放在最前面. 代码如下: 复制代码 代码如下: <?phpclass RandCheckCode{        /*函数名称:g

  • PHP实现变色验证码实例

    复制代码 代码如下: <?php header("Content-type: image/png,charset='utf-8'"); $im = imagecreatetruecolor(400, 30); //白色 $white = imagecolorallocate($im, 255, 255, 255); //红色 $red = imagecolorallocate($im, 255, 0, 0); //黑色 $black=imagecolorallocate($im,

  • php仿QQ验证码的实例分析

    有需要的朋友,参考下吧. 复制代码 代码如下: <?php/** * 仿QQ验证码*///Session保存路径$sessSavePath = dirname(__FILE__)."/../data/sessions/";if(is_writeable($sessSavePath) && is_readable($sessSavePath)){ session_save_path($sessSavePath); }session_start();//获取随机字符$

  • php ci框架验证码实例分析

    php代码: 复制代码 代码如下: <?php class Captcha_code{ var $width='60'; var $num='4'; var $height='20'; var $name='randcode'; public function __construct($conf="") {  if($conf!="")  {   foreach($conf as $key=>$value)   {    $this->$key=$

  • php生成图形验证码几种方法小结

    我们先来检查一下自己的php是不是打开了gd库. 复制代码 代码如下: <?phpif(extension_loaded('gd')) {  echo '你可以使用gd<br>';  foreach(gd_info() as $cate=>$value)    echo "$cate: $value<br>";}else  echo '你没有安装gd扩展';?> 如果有返回信息就正确可以常用使用了例1 复制代码 代码如下: <?php/*

  • PHP验证码函数代码(简单实用)

    效果图: 复制代码 代码如下: <?php    /**  * vCode(m,n,x,y) m个数字  显示大小为n   边宽x   边高y  * micxp  *jb51.net */  session_start();    vCode(4, 15); //4个数字,显示大小为15 function vCode($num = 4, $size = 20, $width = 0, $height = 0) {       !$width && $width = $num * $s

  • PHP5中GD库生成图形验证码(有汉字)

    利用PHP5中GD库生成图形验证码 类似于下面这样 1.利用GD库函数生成图片,并在图片上写指定字符 imagecreatetruecolor 新建一个真彩色图像 imagecolorallocate 为一幅图像分配颜色(调色板) imagestring 绘制字符 imageline 绘制线条 imagesetpixel 打像素点 2.输出图片 imagejpeg($img); PHP实现过程,代码中注释详细,这里不做过多解释 verify.php 复制代码 代码如下: <?php //1.qi

随机推荐