zoukankan      html  css  js  c++  java
  • 制作简单安全的php验证码类代码实例

      本站收录这篇文章制作简单安全的php验证码类代码实例,详细解说文章中相关验证码安全技术与知识,欢迎能给大家一些在这方面的支持和帮助!下面是详细内容:
      一,php验证码类,secoder.class.php
      程序代码(For Alixixi.com)如下:
      <?php
      /**
      *安全验证码
      *
      *安全的验证码要:验证码文字扭曲、旋转,使用不同字体,添加干扰码
      *
      * author流水孟春<cmpan(at)qq.com>
      * link http://labs.yulans.cn/YL_Security_Secoder
      * link http://wiki.yulans.cn/docs/yl/security/secoder
      */
      class YL_Security_Secoder{https://www.hfxskyyj.com/
      /**
      *验证码的session的下标
      *
      * var string
      */
      //public static$seKey='sid.sek ey.ylans.cn';
      public static$seKey='sid';
      public static$expire=3000;//验证码过期时间(s)
      /**
      *验证码中使用的字符,01IO容易混淆,建议不用
      *
      * var string
      */
      public static$codeSet='346789ABCDEFGHJKLMNPQRTUVWXY';
      public static$fontSize=25;//验证码字体大小(px)
      public static$useCurve=true;//是否画混淆曲线
      public static$useNoise=true;//是否添加杂点
      public static$imageH=0;//验证码图片宽
      public static$imageL=0;//验证码图片长
      public static$length=4;//验证码位数
      public static$bg=array(243,251,254);//背景
      protected static$_image=null;//验证码图片实例
      protected static$_color=null;//验证码字体颜色
      /**
      *输出验证码并把验证码的值保存的session中
      *验证码保存到session的格式为:$_SESSION[self::$seKey]=array('code'=>'验证码值','time'=>'验证码创建时间');
      */
      public static function entry(){
      //图片宽(px)
      self::$imageL self::$imageL=self::$length*self::$fontSize*1.5+self::$fontSize*1.5;
      //图片高(px)
      self::$imageH self::$imageH=self::$fontSize*2;
      //建立一幅self::$imageL x self::$imageH的图像
      self::$_image=imagecreate(self::$imageL,self::$imageH);
      //设置背景
      imagecolorallocate(self::$_image,self::$bg[0],self::$bg[1],self::$bg[2]);
      //验证码字体随机颜色
      self::$_color=imagecolorallocate(self::$_image,mt_rand(1,120),mt_rand(1,120),mt_rand(1,120));
      //验证码使用随机字体
      //$ttf=dirname(__FILE__).'/ttfs/'.mt_rand(1,20).'.ttf';4
      $ttf=dirname(__FILE__).'/ttfs/4.ttf';
      if(self::$useNoise){
      //绘杂点
      self::_writeNoise();
      }
      if(self::$useCurve){
      //绘干扰线
      self::_writeCurve();
      }
      //绘验证码
      $code=array();//验证码
      $codeNX=0;//验证码第N个字符的左边距
      for($i=0;$i<self::$length;$i++){
      $code[$i]=self::$codeSet[mt_rand(0,27)];
      $codeNX+=mt_rand(self::$fontSize*1.2,self::$fontSize*1.6);
      //写一个验证码字符
      imagettftext(self::$_image,self::$fontSize,mt_rand(-40,70),$codeNX,self::$fontSize*1.5,self::$_color,$ttf,$code[$i]);
      }
      //保存验证码
      isset($_SESSION)session_start();
      $_SESSION[self::$seKey]['code']=join('',$code);//把校验码保存到session
      $_SESSION[self::$seKey]['time']=time();//验证码创建时间
      header('Cache-Control:private,max-age=0,no-store,no-cache,must-revalidate');
      header('Cache-Control:post-check=0,pre-check=0',false);
      header('Pragma:no-cache');
      header("content-type:image/png");
      //输出图像
      imagepng(self::$_image);
      imagedestroy(self::$_image);
      }
      /**
      *画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数)
      *
      *高中的数学公式咋都忘了涅,写出来
      *正弦型函数解析式:y=Asin(ωx+φ)+b
      *各常数值对函数图像的影响:
      *A:决定峰值(即纵向拉伸压缩的倍数)
      *b:表示波形在Y轴的位置关系或纵向移动距离(上加下减)
      *φ:决定波形与X轴位置关系或横向移动距离(左加右减)
      *ω:决定周期(最小正周期T=2π/∣ω∣)
      *
      */
      protected static function _writeCurve(){
      $A=mt_rand(1,self::$imageH/2);//振幅
      $b=mt_rand(-self::$imageH/4,self::$imageH/4);//Y轴方向偏移量
      $f=mt_rand(-self::$imageH/4,self::$imageH/4);//X轴方向偏移量
      $T=mt_rand(self::$imageH*1.5,self::$imageL*2);//周期
      $w=(2*M_PI)/$T;
      $px1=0;//曲线横坐标起始位置
      $px2=mt_rand(self::$imageL/2,self::$imageL*0.667);//曲线横坐标结束位置
      for($px=$px1;$px<=$px2;$px=$px+0.9){
      if($w!=0){
      $py=$A*sin($w*$px+$f)+$b+self::$imageH/2;//y=Asin(ωx+φ)+b
      $i=(int)((self::$fontSize-6)/4);
      while($i>0){
      imagesetpixel(self::$_image,$px+$i,$py+$i,self::$_color);//这里画像素点比imagettftext和imagestring性能要好很多
      $i--;
      }
      }
      }
      $A=mt_rand(1,self::$imageH/2);//振幅
      $f=mt_rand(-self::$imageH/4,self::$imageH/4);//X轴方向偏移量
      $T=mt_rand(self::$imageH*1.5,self::$imageL*2);//周期
      $w=(2*M_PI)/$T;
      $b=$py-$A*sin($w*$px+$f)-self::$imageH/2;
      $px1=$px2;
      $px2=self::$imageL;
      for($px=$px1;$px<=$px2;$px=$px+0.9){
      if($w!=0){
      $py=$A*sin($w*$px+$f)+$b+self::$imageH/2;//y=Asin(ωx+φ)+b
      $i=(int)((self::$fontSize-8)/4);
      while($i>0){
      imagesetpixel(self::$_image,$px+$i,$py+$i,self::$_color);//这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多
      $i--;
      }
      }
      }
      }
      /**
      *画杂点
      *往图片上写不同颜色的字母或数字
      */
      protected static function _writeNoise(){
      for($i=0;$i<10;$i++){
      //杂点颜色
      $noiseColor=imagecolorallocate(
      self::$_image,
      mt_rand(150,225),
      mt_rand(150,225),
      mt_rand(150,225)
      );
      for($j=0;$j<5;$j++){
      //绘杂点
      imagestring(
      self::$_image,
      5,
      mt_rand(-10,self::$imageL),
      mt_rand(-10,self::$imageH),
      self::$codeSet[mt_rand(0,27)],//杂点文本为随机的字母或数字
      $noiseColor
      );
      }
      }
      }
      /**
      *验证验证码是否正确
      *
      * param string$code用户验证码
      * param bool用户验证码是否正确
      */
      public static function check($code){
      isset($_SESSION)session_start();
      //验证码不能为空
      if(emptyempty($code)emptyempty($_SESSION[self::$seKey])){
      //echo$_SESSION[self::$seKey]['code'].'1';
      return false;
      }
      //session过期
      if(time()-$_SESSION[self::$seKey]['time']>self::$expire){
      unset($_SESSION[self::$seKey]);
      //echo$_SESSION[self::$seKey]['code'].'2';
      return false;
      //return 0;
      }
      //if($code==$_SESSION[self::$seKey]['code']){
      if(strtoupper($code)==$_SESSION[self::$seKey]['code']){//不区分大小写比较
      //echo$_SESSION[self::$seKey]['code'].'3';
      return true;
      }
      //echo$_SESSION[self::$seKey]['code'].'4';
      return false;
      }
      }
      //useage
      /*
      YL_Security_Secoder::$useNoise=false;//要更安全的话改成true
      YL_Security_Secoder::$useCurve=true;
      YL_Security_Secoder::entry();
      */
      /*
      //验证验证码
      if(!YL_Security_Secoder::check( $_POST['secode'])){
      print'error secode';
      }
      */
      二,调用方法
      1,显示验证码页面code.php
      程序代码(For Alixixi.com)如下:
      <?php
      session_start();
      require'secoder.class.php';//先把类包含进来,实际路径根据实际情况进行修改。
      $vcode=new YL_Security_Secoder();//实例化一个对象
      $vcode->entry();
      ?>
      2,检查验证码是否正确
      程序代码(For Alixixi.com)如下:
      <?php
      session_start();
      require'secoder.class.php';//先把类包含进来,实际路径根据实际情况进行修改。
      $vcode=new YL_Security_Secoder();//实例化一个对象
      //$vcode->entry();
      $code=$_GET['code'];
      echo$vcode->check($code);
      //$_SESSION['code']=$vc->getCode();//验证码保存到SESSION中
      ?>
      3,验证码输入框调用页面
      程序代码(For Alixixi.com)如下:
      <img id="messageImg"src='images/tishis2.gif'width='16'height='16'>单击图片重新获取验证码<br>
      <a href="#"><img src="code.php"onclick="javascript:this.src='code.php?tm='+Math.random();"/>

  • 相关阅读:
    C#中get和set的写法
    FineUI中Newtonsoft.Json版本报错解决办法
    ExtAspNet和FineUI未将对象引用设置到对象的实例
    【转载】写runat="server"有什么用
    (object sender,EventArgs e)是什么?
    【转载】onclick与onCommand的区别
    简单总结------redis
    将list等分成n份
    将List 分成n个长度由调用者指定的子List
    CountDownLatch 我的应用场景
  • 原文地址:https://www.cnblogs.com/zqw111/p/12922587.html
Copyright © 2011-2022 走看看