PHP生成圖形驗證碼(加強干擾型)

2020-07-16 10:05:52

驗證碼使用場景

我們在開發系統的過程中,基本所有的系統都會涉及到登入模組,其中驗證碼功能是這裡面必不可少的一塊,是防止系統被爆破的有效途徑。所謂道高一尺魔高一丈,現在的驗證碼越來越複雜先進,常見的字母數位驗證碼,行為驗證碼。本文詳細介紹簡單的字母數位驗證碼。

程式碼

<?php

/*********************************************************************************
 * InitPHP 3.8.2 國產PHP開發框架   擴充套件類庫-驗證碼
 *-------------------------------------------------------------------------------
 * 版權所有: CopyRight By initphp.com
 * 您可以自由使用該原始碼,但是在使用過程中,請保留作者資訊。尊重他人勞動成果就是尊重自己
 *-------------------------------------------------------------------------------
 * Author:zhuli Dtime:2014-11-25
 ***********************************************************************************/
class Code
{

    private $charset = "abcdefghjklmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";   //隨機因子
    private $code;     //驗證碼文字
    private $codelen = 4;    //驗證碼顯示幾個文字
    private $width = 100;   //驗證碼寬度
    private $height = 40;   //驗證碼高度
    private $img;       //驗證碼資源控制代碼
    private $font;     //指定的字型
    private $fontsize = 20;  //指定的字型大小
    private $fontcolor;     //字型顏色  隨機

    //構造類  編寫字型
    public function __construct()
    {
        $this->font = '/outputs/font/font.ttf';
    }

    //建立4個隨機碼
    private function createCode()
    {
        $_leng = strlen($this->charset) - 1;
        for ($i = 1; $i <= $this->codelen; $i++) {
            $this->code .= $this->charset[mt_rand(0, $_leng)];
        }
//        session_start();
//        $_SESSION['VerifyCode'] = strtolower($this->code);
        Session::set('VerifyCode', strtolower($this->code));
        return $this->code;
    }

    //建立背景
    private function createBg()
    {
        //建立畫布 給一個資源jubing
        $this->img = imagecreatetruecolor($this->width, $this->height);
        //背景顏色
        $color = imagecolorallocate($this->img, mt_rand(157, 255), mt_rand(157, 255), mt_rand(157, 255));
        //畫出一個矩形
        imagefilledrectangle($this->img, 0, $this->height, $this->width, 0, $color);
    }

    //建立字型
    private function createFont()
    {
        $_x = ($this->width / $this->codelen);   //字型長度
        for ($i = 0; $i < $this->codelen; $i++) {
            //文字顏色
            $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
            //資源控制代碼 字型大小 傾斜度 字型長度  字型高度  字型顏色  字型  具體文字
            imagettftext($this->img, $this->fontsize, mt_rand(-30, 30), $_x * $i + mt_rand(1, 5), $this->height / 1.4, $color, $this->font, $this->code[$i]);
        }
    }

    //隨機線條
    private function createLine()
    {
        //隨機線條
        for ($i = 0; $i < 6; $i++) {
            $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
            imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
        }
        //隨機雪花
        for ($i = 0; $i < 45; $i++) {
            $color = imagecolorallocate($this->img, mt_rand(220, 255), mt_rand(220, 255), mt_rand(220, 255));
            imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
        }
    }

    //輸出背景
    private function outPut()
    {
        //生成檔頭
        header('Content-type:image/png');
        //輸出圖片
        imagepng($this->img);
        //銷毀結果集
        imagedestroy($this->img);
    }

    //對外輸出
    public function doimg()
    {
        //載入背景
        $this->createBg();
        //載入檔案
        $this->createCode();
        //載入線條
        $this->createLine();
        //載入字型
        $this->createFont();
        //載入背景
        $this->outPut();
    }

    //獲取驗證碼
    public function getCode()
    {
        return strtolower($this->code);
    }

    //驗證驗證碼
    public function checkCode($code, $clear = false)
    {
//        session_start();
        if (Session::get('VerifyCode') == strtolower($code)) {
            if($clear) $this->clearCode();
            return true;
        }
        if($clear) $this->clearCode();
        return false;
    }

    //清除驗證碼
    public function clearCode()
    {
        Session::del('VerifyCode');
//        session_start();
//        unset ($_SESSION['VerifyCode']);
    }
}

驗證

ob_clean();
$verify = new Code();
$verify->doimg();

這樣即可輸出如下驗證碼

WX20200429-205016.png

可以調整引數控制驗證碼的大小,干擾項等。

拓展

接下來介紹下拓展的功能,怎麼加強驗證碼的干擾項,怎麼結合到專案麗進行登入驗證。

1. 加強干擾

首先我們可以看到上面的截圖中少數線條,如果外者使用分析工具來解碼,那麼會很簡單的就解出我們的驗證碼,這時候就需要新增線條的數量,在程式碼中找到以下程式碼並修改

//隨機線條
private function createLine()
{
    //隨機線條 
    for ($i = 0; $i < 6; $i++) {
        $color = imagecolorallocate($this->img, mt_rand(0, 156), mt_rand(0, 156), mt_rand(0, 156));
        imageline($this->img, mt_rand(0, $this->width), mt_rand(0, $this->height), mt_rand(0, $this->width), mt_rand(0, $this->height), $color);
    }
    //隨機雪花
    for ($i = 0; $i < 45; $i++) {
        $color = imagecolorallocate($this->img, mt_rand(220, 255), mt_rand(220, 255), mt_rand(220, 255));
        imagestring($this->img, mt_rand(1, 5), mt_rand(0, $this->width), mt_rand(0, $this->height), '*', $color);
    }
}

上面的數位6可以慢慢調整,然後檢視效果直到滿意。同時可以看到驗證碼中有很多雪花效果,這個也是干擾項,可以修改上面的數位45來調整到自己滿意的結果。

注意:程式碼中的$charset變數,驗證碼是從這邊隨機取字元來生存驗證,由於小寫的i和L展示的效果很難分辨,所以我們去除了i字元。

2. 接入專案驗證

新建個檔案,程式碼如下

<?php
ob_clean();
$verify = new Code();
$verify->doimg();

然後在現有的系統登入頁面引入這個介面即可展示驗證碼,在使用者填寫提交之後,伺服器端做以下驗證

//驗證驗證碼
public function checkCode($code, $clear = false)
{
    if (Session::get('VerifyCode') == strtolower($code)) {
        if($clear) $this->clearCode();
            return true;
    }
    if($clear) $this->clearCode();
    return false;
}
//清除驗證碼
public function clearCode()
{
    Session::del('VerifyCode');
}

至此,驗證碼的生成以及驗證流程都已完成。

以上就是PHP生成圖形驗證碼(加強干擾型)的詳細內容,更多請關注TW511.COM其它相關文章!